Spring Cloud OAuth2Authentication返回NullPointerException

时间:2017-04-20 12:16:15

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

我正在慢慢了解Spring Cloud Security。我已经创建了一个授权服务,它在授权和返回令牌时起作用,但在使用该令牌时,从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());
    }
}

3 个答案:

答案 0 :(得分:0)

最后,我得到了这样的工作:

<强> 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);
    }
}

答案 1 :(得分:0)

我遇到了同样的问题,似乎是新版本的bug。我更改了Spring Boot 1.5.9.RELEASE,Spring Cloud Edgware.RELEASE支持Spring Boot 1.4.4.RELEASE,Spring Cloud Camden.SR5,问题消失了。

答案 2 :(得分:0)

设置security.oauth2.resource.filter-order=3配置属性可恢复以前版本中使用的顺序。有关更多详细信息,请参见enter link description here