java - Spring Cloud OAuth2Authentication 返回 NullPointerException

标签 java spring-security spring-security-oauth2 spring-cloud-security

我正在慢慢地了解 Spring Cloud Security。我创建了一个授权服务,它在授权和返回 token 时起作用,但在使用该 token 时以及从 OAuth2Authentication 获取这些信息时不会返回任何当前用户详细信息。这两行返回一个 NPE:

userInfo.put("user", user.getUserAuthentication().getPrincipal());
            userInfo.put("authorities", AuthorityUtils.authorityListToSet(user.getUserAuthentication().getAuthorities()));

OAuth2Authentication user 未实例化并且为 null,但我知道它应该默认由 Spring Security 实例化。也许我缺少一些配置 bean?提前致谢!

Application.class

@SpringBootApplication
@RestController
@EnableResourceServer
@EnableAuthorizationServer
public class AuthorizationServiceApplication {

    @RequestMapping(value = {"/user"}, produces = "application/json")
    public Map <String, Object> user (OAuth2Authentication user) {
        Map <String, Object> userInfo = new HashMap <>();
        userInfo.put("user", user.getUserAuthentication().getPrincipal());
        userInfo.put("authorities", AuthorityUtils.authorityListToSet(user.getUserAuthentication().getAuthorities()));
        return userInfo;
    }

    public static void main (String[] args) {
        SpringApplication.run(AuthorizationServiceApplication.class, args);
    }
}

OAuth2Config.class

@Configuration
public class OAuth2Config extends AuthorizationServerConfigurerAdapter {

    @Value("${token.secret}")
    private String secret;
    private AuthenticationManager authenticationManager;
    private UserDetailsService userDetailsService;

    public OAuth2Config (AuthenticationManager authenticationManager, UserDetailsService userDetailsService) {
        this.authenticationManager = authenticationManager;
        this.userDetailsService = userDetailsService;
    }

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory()
                .withClient("eagleeye")
                .secret(secret)
                .authorizedGrantTypes("refresh_token", "password", "client_credentials")
                .scopes("webclient", "mobileclient");
    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints
                .authenticationManager(authenticationManager)
                .userDetailsService(userDetailsService);
    }
}

WebSecurityConfigurer.class

@Configuration
public class WebSecurityConfigurer extends WebSecurityConfigurerAdapter {

    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean () throws Exception {
        return super.authenticationManagerBean();
    }

    @Override
    @Bean
    public UserDetailsService userDetailsServiceBean() throws Exception {
        return super.userDetailsServiceBean();
    }

    // TODO: implemented DB stuff
    @Override
    protected void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
        authenticationManagerBuilder
                .inMemoryAuthentication()
                .withUser("deniss").password("deniss1").roles("USER")
                .and()
                .withUser("oksana").password("oksana").roles("USER, ADMIN");
    }

    private CsrfTokenRepository csrfTokenRepository() {
        HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository();
        repository.setSessionAttributeName("_csrf");
        return repository;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().csrfTokenRepository(csrfTokenRepository());
    }
}

最佳答案

最后我让它像这样工作:

Application.class

@SpringBootApplication
@RestController
@EnableResourceServer
public class AuthorizationServiceApplication {

    private final Logger log = LoggerFactory.getLogger(this.getClass());

    @RequestMapping("/user")
    public Principal user(Principal user) {
        log.info("User information display for User: " + user.getName());
        return user;
    }

    @Bean
    UserDetailsService userDetailsService() {
        InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
        manager.createUser(User.withUsername("deniss").password("deniss").roles("USER").build());
        return manager;
    }

    public static void main (String[] args) {
        SpringApplication.run(AuthorizationServiceApplication.class, args);
    }
}

OAuth2Config.java

@Configuration
@EnableAuthorizationServer
public class OAuth2Config extends AuthorizationServerConfigurerAdapter {

    //TODO: refactor to recieve this info from config server
    @Value("${token.secret}")
    private String secret;

    @Autowired
    private AuthenticationManager authenticationManager;

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints.authenticationManager(authenticationManager);
    }

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory()
                .withClient("eagleeye")
                .secret(secret)
                .authorizedGrantTypes("refresh_token", "password", "client_credentials")
                .scopes("webclient", "mobileclient");
    }
}

SecurityConfigurer.class

@Configuration
@EnableGlobalAuthentication
public class SecurityConfigurer extends GlobalAuthenticationConfigurerAdapter {

    @Autowired
    private UserDetailsService userDetailsService;

    // TODO: implemented DB stuff
    @Override
    public void init(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
        authenticationManagerBuilder.userDetailsService(this.userDetailsService);
    }
}

关于java - Spring Cloud OAuth2Authentication 返回 NullPointerException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43519278/

相关文章:

java.sql.SQLException : [Microsoft][ODBC Microsoft Access Driver] Operation must use an updateable query

spring - Spring Security不会发布到提供的登录处理URL

java - 如何使用 JASIG SSO 同时验证两个客户端

java - OAuth2 : Confirmation Approval is not working, 即使我单击“批准”按钮也拒绝

spring - 实现 Spring OAuth2,从不同设备获取相同的访问 token

java - Swing + MigLayout,其他组件的动态增长和收缩

java - 为 Eclipse 的 .p2 树 ("bundle pool"使用不同的位置)

java - 按字符串长度排序

java - 如何在Web应用中构建良好的安全架构?

spring - 添加spring-security-oauth2后无法实例化接口(interface)org.springframework.context.ApplicationListener