Spring OAuth2 использует неправильные данные аутентификации для токена

#spring-mvc #spring-security #spring-security-oauth2

#spring-mvc #spring-безопасность #spring-security-oauth2

Вопрос:

У меня есть следующая конфигурация в Spring Security с OAuth2:

   @Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
//@EnableOAuth2Sso
public class FVSecurityConfig extends WebSecurityConfigurerAdapter { 
    @Autowired
  public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
    auth
      .inMemoryAuthentication()
        .withUser("user")
          .password("secret")
          .roles("USER", "ROLE1")
          .and()
        .withUser("admin")
          .password("password")
          .roles("ADMIN","USER");
  }

   @Override
  protected void configure(HttpSecurity http) throws Exception {
    http
      .csrf().disable()
      .anonymous().disable()
      .authorizeRequests()
        .antMatchers("/api/admin/**").hasRole("ADMIN")
        .antMatchers("/api/**").hasRole("USER")
        .anyRequest().authenticated() 
        .and().exceptionHandling().accessDeniedHandler(new OAuth2AccessDeniedHandler())
        .and()
    .formLogin();
  }
 

Конфигурация сервера ресурсов:

  @Configuration
@EnableAuthorizationServer
public class OAuth2Config extends AuthorizationServerConfigurerAdapter {

@Override
    public void configure(ClientDetailsServiceConfigurer clients) 
      throws Exception {
        clients.inMemory()
               .withClient("sampleClient")
               .authorizedGrantTypes("implicit")
               .scopes("read")
               .autoApprove(true)
               .accessTokenValiditySeconds(30)
               .and()
               .withClient("user")
               .secret("secret")
               .scopes("read", "write")
               .autoApprove(true)
               .authorizedGrantTypes(
                "password","authorization_code", "refresh_token")
               .and()
               .withClient("admin")
               .secret("password")
               .scopes("read", "write", "custom")
               .autoApprove(true)
               .authorizedGrantTypes(
                "password","authorization_code", "refresh_token");
    }
 

И следующий контроллер Rest

 @RestController
public class OAuthTestController {

@PreAuthorize("hasRole('ROLE_ROLE1') and #oauth2.hasScope('read')")
    @RequestMapping(value="/api/user/test1", method = RequestMethod.GET)
    public String testGETWithRole() {
        return  "[GET] Needs role ROLE1";
    }

    @RequestMapping(value="/api/admin/test1", method = RequestMethod.GET)
public String testWithAdminRole() {
    return  "[GET] Needs Admin role";
}
 

И сервер ресурсов:

  @Configuration
 @EnableResourceServer
 public class ResourceServer extends ResourceServerConfigurerAdapter {

private static final String RESOURCE_ID = "my_rest_api";

@Override
public void configure(ResourceServerSecurityConfigurer resources) {
    resources.resourceId(RESOURCE_ID).stateless(false);
}


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

}

По сути, я ожидаю, что Spring будет использовать OAuth2 для аутентификации и использовать роли безопасности spring для разрешения доступа к ресурсам. Я сгенерировал токен администратора и затем токен пользователя. Я ожидаю, что при использовании токена администратора будет иметь доступ к ресурсу / api / admin, а при использовании токена пользователя — нет. Я только что заметил, что вход в форму запрашивается не всегда, поэтому я полагаю, что Spring запоминает аутентифицированного пользователя.

Когда я использовал токен администратора, мне было отказано в доступе. При отладке в источниках Spring я заметил, что аутентификация была экземпляром UserNamePasswordAuthenticationPassword с данными пользователя, а не администратора, как ожидалось. Я полагаю, это потому, что в прошлый раз я использовал эти учетные данные в форме входа. Это способ заставить spring использовать учетные данные для соответствующего токена или заставлять Spring показывать форму входа каждый раз?

PS Я использую Postman для тестирования API.

Спасибо.

Комментарии:

1. где у вас есть конфигурация вашего сервера ресурсов? Я вижу только конфигурацию сервера авторизации.

2. @bilak, я обновил сообщение с помощью сервера ресурсов.