OAuth2 with Spring Boot REST application - cannot access resource with token

匿名 (未验证) 提交于 2019-12-03 01:27:01

问题:

I want to use OAuth2 for my REST spring boot project. Using some examples I have created configuration for OAuth2:

@Configuration public class OAuth2Configuration {      private static final String RESOURCE_ID = "restservice";      @Configuration     @EnableResourceServer     protected static class ResourceServerConfiguration extends           ResourceServerConfigurerAdapter {          @Override         public void configure(ResourceServerSecurityConfigurer resources) {             // @formatter:off             resources                     .resourceId(RESOURCE_ID);             // @formatter:on         }          @Override         public void configure(HttpSecurity http) throws Exception {             // @formatter:off             http                     .anonymous().disable()                     .authorizeRequests().anyRequest().authenticated();             // @formatter:on         }      }      @Configuration     @EnableAuthorizationServer     protected static class AuthorizationServerConfiguration extends              AuthorizationServerConfigurerAdapter {          private TokenStore tokenStore = new InMemoryTokenStore();          @Autowired         @Qualifier("authenticationManagerBean")         private AuthenticationManager authenticationManager;          @Autowired         private UserDetailsServiceImpl userDetailsService;          @Override         public void configure(AuthorizationServerEndpointsConfigurer endpoints)             throws Exception {           // @formatter:off           endpoints                   .tokenStore(this.tokenStore)                   .authenticationManager(this.authenticationManager)                   .userDetailsService(userDetailsService);           // @formatter:on         }          @Override         public void configure(ClientDetailsServiceConfigurer clients) throws Exception {             // @formatter:off             clients                   .inMemory()                   .withClient("clientapp")                   .authorizedGrantTypes("password", "refresh_token", "trust")                   .authorities("USER")                   .scopes("read", "write")                   .resourceIds(RESOURCE_ID)                   .secret("clientsecret")                   .accessTokenValiditySeconds(1200)                   .refreshTokenValiditySeconds(3600);             // @formatter:on         }          @Bean         @Primary         public DefaultTokenServices tokenServices() {             DefaultTokenServices tokenServices = new DefaultTokenServices();             tokenServices.setSupportRefreshToken(true);             tokenServices.setTokenStore(this.tokenStore);             return tokenServices;         }     } }

This is my SecurityConfiguration class:

@Configuration @EnableWebSecurity @Order(1) public class SecurityConfiguration extends WebSecurityConfigurerAdapter {      @Autowired     private UserDetailsService userDetailsService;      @Override     protected void configure(HttpSecurity http) throws Exception {         http.csrf().disable();         http                 .authorizeRequests().antMatchers("/api/register").permitAll()                 .and()                 .authorizeRequests().antMatchers("/api/free").permitAll()                 .and()                 .authorizeRequests().antMatchers("/oauth/token").permitAll()                 .and()                 .authorizeRequests().antMatchers("/api/secured").hasRole("USER")                 .and()                 .authorizeRequests().anyRequest().authenticated();     }      @Override     @Bean     public AuthenticationManager authenticationManagerBean() throws Exception {         return super.authenticationManagerBean();     }      @Bean     public PasswordEncoder passwordEncoder() {         return new BCryptPasswordEncoder();     }  }

I tried to check my application with 2 simple requests:

@RequestMapping(value = "/api/secured", method = RequestMethod.GET) public String checkSecured(){     return "Authorization is ok"; }  @RequestMapping(value = "/api/free", method = RequestMethod.GET) public String checkFree(){     return "Free from authorization"; }

Firstly I checked two requests:

/api/free returned code 200 and the string "Free from authorization"

/api/secured returned {"timestamp":1487451065106,"status":403,"error":"Forbidden","message":"Access Denied","path":"/api/secured"}

And it seems that they work fine.

Then I got access_token (using credentials from my users database)

/oauth/token?grant_type=password&username=emaila&password=emailo

Response:

{"access_token":"3344669f-c66c-4161-9516-d7e2f31a32e8","token_type":"bearer","refresh_token":"c71c17e4-45ba-458c-9d98-574de33d1859","expires_in":1199,"scope":"read write"}

Then I tried to send a request (with the token I got) for resource which requires authentication:

/api/secured?access_token=3344669f-c66c-4161-9516-d7e2f31a32e8

Here is response:

{"timestamp":1487451630224,"status":403,"error":"Forbidden","message":"Access Denied","path":"/api/secured"}

I cannot understand why access is denied. I am not sure in configurations and it seems that they are incorrect. Also I still do not clearly understand relationships of methods configure(HttpSecurity http) in class which extends WebSecurityConfigurerAdapter and in another which extends ResourceServerConfigurerAdapter. Thank you for any help!

回答1:

If you are using spring boot 1.5.1 or recently updated to it, note that they changed the filter order for spring security oauth2 (Spring Boot 1.5 Release Notes).

According to the release notes, try to add the following property to application.properties/yml, after doing that the resource server filters will be used after your other filters as a fallback - this should cause the authorization to be accepted before falling to the resource server:

security.oauth2.resource.filter-order = 3

You can find a good answer for your other questions here: https://stackoverflow.com/questions/28537181



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!