首页 > 解决方案 > 检索访问令牌后,Spring Boot OAuth2“访问此资源需要完全身份验证”

问题描述

我正在用 OAuth2 应用程序编写 Spring Boot。我的课程是:

AuthorizationServerConfig.class

<pre>
    @Configuration
    @EnableAuthorizationServer
    public class AuthorizationServerConfig extends 
    AuthorizationServerConfigurerAdapter {
    private static String REALM="CRM_REALM";
    private static final int TEN_DAYS = 60 * 60 * 24 * 10;
    private static final int ONE_DAY = 60 * 60 * 24;
    private static final int THIRTY_DAYS = 60 * 60 * 24 * 30; 

    @Autowired
    private DataSource dataSource;

    @Autowired
    private TokenStore tokenStore;

    @Autowired
    private UserApprovalHandler userApprovalHandler;

    @Autowired
    @Qualifier("authenticationManagerBean")
    private AuthenticationManager authenticationManager;

    @Autowired
    private CrmUserDetailsService crmUserDetailsService;

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws 
    Exception {

        // clients.jdbc(dataSource);

        clients.inMemory()
            .withClient("crmClient1")
            .secret("crmSuperSecret")
            .authorizedGrantTypes("password", "refresh_token")
            .authorities("ROLE_CLIENT", "ROLE_TRUSTED_CLIENT")
            .scopes("read", "write", "trust")
            //.accessTokenValiditySeconds(ONE_DAY)
            .accessTokenValiditySeconds(300)
            .refreshTokenValiditySeconds(THIRTY_DAYS);

    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) 
    throws Exception {

    endpoints.tokenStore(tokenStore).userApprovalHandler(userApprovalHandler)
        .authenticationManager(authenticationManager)
        .userDetailsService(crmUserDetailsService);
    }

    @Override
    public void configure(AuthorizationServerSecurityConfigurer oauthServer) 
    throws Exception {
        oauthServer.realm(REALM);
    }
}
</pre>

资源服务器配置类

<pre>
    @Configuration
    @EnableResourceServer
    public class ResourceServerConfig extends ResourceServerConfigurerAdapter {

    @Override
    public void configure(HttpSecurity http) throws Exception {
        //-- define URL patterns to enable OAuth2 security
        http.
        anonymous().disable()
        .requestMatchers().antMatchers("/api/**")
        .and().authorizeRequests()
        .antMatchers("/api/**").access("hasRole('ADMIN') or hasRole('USER')")
        .and().exceptionHandling().accessDeniedHandler(new 
    OAuth2AccessDeniedHandler());
    }

    }
</pre>

安全配置类

<pre>
    @Configuration
    @EnableWebSecurity
    public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private DataSource dataSource;

    @Autowired
    private ClientDetailsService clientDetailsService;

    @Autowired
    private CrmUserDetailsService crmUserDetailsService;


    @Override
    @Order(Ordered.HIGHEST_PRECEDENCE)
    protected void configure(HttpSecurity http) throws Exception {
        http
        .sessionManagement()
        .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
        .and()
        .csrf().disable()
        .authorizeRequests()
        .antMatchers("/about").permitAll() 
        .antMatchers("/signup").permitAll()
        .antMatchers("/oauth/token").permitAll()
        //.antMatchers("/api/**").authenticated()
        .anyRequest().authenticated()
        .and()
        .httpBasic()
            .realmName("CRM_REALM");
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception 
    {
        auth.userDetailsService(crmUserDetailsService)
            .passwordEncoder(passwordEncoder());
    }

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


    @Bean
    public TokenStore tokenStore() {
        return new InMemoryTokenStore();
    }


    @Bean
    @Autowired
    public TokenStoreUserApprovalHandler userApprovalHandler(TokenStore 
    tokenStore){
        TokenStoreUserApprovalHandler handler = new 
    TokenStoreUserApprovalHandler();
        handler.setTokenStore(tokenStore);
        handler.setRequestFactory(new 
    DefaultOAuth2RequestFactory(clientDetailsService));
        handler.setClientDetailsService(clientDetailsService);
        return handler;
    }

    @Bean
    @Autowired
    public ApprovalStore approvalStore(TokenStore tokenStore) throws Exception {
        TokenApprovalStore store = new TokenApprovalStore();
        store.setTokenStore(tokenStore);
        return store;
    }

    @Bean
    public PasswordEncoder passwordEncoder() {

        return new BCryptPasswordEncoder();
    }   

    }
</pre>

SecurityWebApplicationInitializer.class

<pre>
    public class SecurityWebApplicationInitializer extends 
    AbstractSecurityWebApplicationInitializer {

    }
</pre>
MethodSecurityConfig.class
<pre>
    @Configuration
    @EnableGlobalMethodSecurity(prePostEnabled = true)
    public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration 
    {

    @Override
    protected MethodSecurityExpressionHandler createExpressionHandler() {
        return new OAuth2MethodSecurityExpressionHandler();
    }
    }
</pre>

注册服务类

<pre>
    @Service
    @Transactional
    public class SignupService {

    @Autowired
    private UserRepository userRepository;

    @Autowired
    PasswordEncoder passwordEncoder;

    public User addUser(User user) {
        user.setPassword(passwordEncoder.encode(user.getPassword()));
        return userRepository.save(user);
    }

    /**
     * 
     * set up a default customer with two roles USER and ADMIN
     * 
     */
    @PostConstruct
    private void setupDefaultUser() {

        if (userRepository.count() == 0) {
            userRepository.save(new User("crmadmin",
                                    passwordEncoder.encode("adminpass"), 
                                    Arrays.asList(new UserRole("USER"), new 
    UserRole("ADMIN"))));
        }       
    }

    }
</pre>

在我发送请求 localhost:8080/oauth/token 并获得 access_token 和 refresh_token 之后,当我尝试使用 Authorization: Bearer (access_token) 发送 api 请求时,我得到了错误:

<pre>
    {
    "timestamp": 1534343851414,
    "status": 401,
    "error": "Unauthorized",
    "message": "Full authentication is required to access this resource",
    "path": "/api/customers"
    }
</pre>

你可以帮帮我吗?

标签: spring-bootoauth-2.0

解决方案


推荐阅读