Unable to access resources with access_token : spring boot Oauth2

后端 未结 5 1156
南方客
南方客 2020-12-19 04:00

I am trying to implement Oauth2 in my existing application.Initially I have added spring security and then tried to add oauth2, After adding configuration I am able to gener

相关标签:
5条回答
  • 2020-12-19 04:29

    You should use hasRole directly on your antmatcher instead of a string inside the access() function. This will evaluate the hasRole correctly and correctly determine that the user has access to the requested resource.

    This will result in the following code for ResourceServer.java:

    @Configuration
    @EnableResourceServer
    public class ResourceServer extends ResourceServerConfigurerAdapter {
    
        @Override
        public void configure(HttpSecurity http) throws Exception {
            http.anonymous().disable()
                    .requestMatchers().antMatchers("/patients/**").and().authorizeRequests()
                    .antMatchers("/patient/**").hasRole('USER')
                    .and().exceptionHandling().accessDeniedHandler(new OAuth2AccessDeniedHandler());
        }
    
    }
    
    0 讨论(0)
  • 2020-12-19 04:45

    I suspect the problem might be the way you save/load roles. In spring security there is a default prefix for roles: ROLE_. So in your DB (storage) you need to save them as ROLE_FOO for example and then you can use hasRole('FOO')

    I found the same problem here, and my answer seemed to solve the problem: https://stackoverflow.com/a/43568599/4473822

    The person that got the issue also had 403 - Forbidden and saving the roles correctly in the DB solved the problem.

    You can also change the default prefix but I would not recommend it unless you want to mess with spring a bit.

    0 讨论(0)
  • 2020-12-19 04:47

    Please change the code like below in ResourceServer:

    Have a look at this line:

    http.anonymous().disable()
                    .requestMatchers().antMatchers("/patients/**","/patient/**")
    

    Since "/patient/"**, is not added as part of request matcher, the request is actually was handled by other configuration

    package project.configuration;
    
    import org.springframework.context.annotation.Configuration;
    import org.springframework.security.config.annotation.web.builders.HttpSecurity;
    import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
    import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
    import org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler;
    
    
    @Configuration
    @EnableResourceServer
    public class ResourceServer extends ResourceServerConfigurerAdapter {
    
        @Override
        public void configure(HttpSecurity http) throws Exception {
            http.anonymous().disable()
                    .requestMatchers().antMatchers("/patients/**","/patient/**").and().
                    authorizeRequests().antMatchers("*/patient/**").hasRole("USER")
                    .and().exceptionHandling().accessDeniedHandler(new OAuth2AccessDeniedHandler());
        }
    
    }
    
    0 讨论(0)
  • 2020-12-19 04:49

    In the example, I have the same problem, after so much search and try, I solved it by adding the below one.

    After added @Order(10) on OAuth2AuthorizationServer,@Order(20) on OAuth2ResourceServer, @Order(30) on SecurityConfig,

    I finally could get resources via an access token. in @Order, Lower values have higher priority, so the reason why we can’t get resources via access token must be that SecurityConfig has higher priority than OAuth2ResourceServer.

    So try to add @Order(30) on SecurityConfiguration, @Order(10) on SecurityOAuth2Configuration, and @Order(20) on ResourceServer.

    0 讨论(0)
  • 2020-12-19 04:50

    First off, you have two similar methods that modify the AuthenticationManagerBuilder

    @Autowired
    public void configAuthentication(AuthenticationManagerBuilder auth) throws Exception {
    

    and

    @Override
    public void configure(AuthenticationManagerBuilder auth) throws Exception {
    

    Is there a reason they both are there? I do not have this in my config set up.

    Furthermore, your query might not be working properly. You should follow some guidelines into how to set up a user service to handle the loaduserbyusername call and the auth object with one. As a note: I do not have the same AuthenticationManagerBuilder set up as you, I have mine configured to use a userdetails service, along with a password Encoder like so.

        auth.userDetailsService(securityUserService)
            .passwordEncoder(passwordEncoders.userPasswordEncoder());
    

    If that doesn't help, here's an alternative way of configuring:

    Change the class that extends WebSecurityConfigurerAdapter to only concern itself with the token endpoint.

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
        .authorizeRequests()
            .antMatchers("/api/oauth/**").permitAll()
            .and()
        .csrf()
            .disable();
    }
    

    Now in your ResourceServerConfigurerAdapter, have the configuration worry about the stuff in the resource server. Please note, this will work only if your AuthenticationManagerBuilder configuration is properly loading the Role correctly. As other's have noted, Spring has the prefix ROLE_. Which for some reason you are retrieving using a query, and they're authorities.

    @Override
    public void configure(HttpSecurity http) throws Exception {
    
        http.csrf().disable()
        .requestMatchers()
            .antMatchers("/api/**")
            .and()
        .authorizeRequests()
            .antMatchers("/api/**").access("hasRole('USER')")
            .and()
        .exceptionHandling()
        .accessDeniedHandler(new OAuth2AccessDeniedHandler());
    
    }
    

    In my AuthServerConfig file I Do not have the following annotations:

    @EnableGlobalMethodSecurity(prePostEnabled = true)
    @Import(SecurityConfiguration.class)
    

    I configure the AuthorizationServerSecurityConfigurer differently than the tutorial you followed, mine is the following:

    @Override
    public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
    
        oauthServer.tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated()");
    }
    

    My ClientDetailsServiceConfigurer is still in memory so that's different as well. My AuthorizationServerEndpointsConfigurer is slightly different too, I only add a tokenstore, an enhancer chain (Don't worry about this, it's extra), and an authenticationManager

        endpoints
            .tokenStore(tokenStore())
            .tokenEnhancer(tokenEnhancerChain)
            .authenticationManager(authenticationManager);
    
    0 讨论(0)
提交回复
热议问题