Как обновить токен доступа с токеном обновления в oauth2 весной? - PullRequest
0 голосов
/ 04 февраля 2019

Я очень новичок в Spring, и это моя первая попытка безопасности весны с помощью oauth2.Я реализовал OAuth2 с пружинной защитой и получаю токен доступа и токен обновления.Однако при отправке токена обновления для получения нового токена доступа я получил «ossoprovider.endpoint.TokenEndpoint - IllegalStateException, требуется UserDetailsService.»

Похоже, что для решения аналогичной проблемы другими пользователями присоединяется UserDetailsService с помощьюконечная точка.

Итак, я сделал то же самое, и теперь, когда я пытаюсь отправить запрос с помощью grant_type: refresh_token и refresh_token: THE TOKEN вместе с идентификатором клиента и секретом, я получаю сообщение об ошибке, что пользователь не найден.

См. Класс WebSecurityConfiguration ниже:

@EnableWebSecurity
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter{

    @Autowired
    private UserDetailsService customUserDetailsService;

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

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

    @Override
     protected void configure (HttpSecurity http) throws Exception {

        http.csrf().disable()
        .antMatcher("/**")
        .authorizeRequests()
        .antMatchers("/login**")
        .permitAll()
        .anyRequest()
        .authenticated();
     }

    public PasswordEncoder encoder() {
        return NoOpPasswordEncoder.getInstance();
    }
}

См. Класс AuthorizationServerConfiguration ниже:

@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private DataSource dataSource;

    @Autowired 
    private CustomUserDetailsService userDetailsService;

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

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

        clients.jdbc(dataSource);
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

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

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

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

}

См. Класс ResourceServerConfiguration ниже:

@Configuration
@EnableResourceServer
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter{


    @Autowired
    DataSource dataSource;

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

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
        resources.resourceId("scout").tokenStore(tokenStore());
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {

        http
         .authorizeRequests (). antMatchers ("/oauth/token", "/oauth/authorize **").permitAll();  
         // .anyRequest (). authenticated (); 
         http.requestMatchers (). antMatchers ("/api/patients/**") // Deny access to "/ private"
         .and (). authorizeRequests ()
         .antMatchers ("/api/patients/**"). access ("hasRole ('PATIENT')") 
         .and (). requestMatchers (). antMatchers ("/api/doctors/**") // Deny access to "/ admin"
         .and (). authorizeRequests ()
         .antMatchers ("/api/doctors/**"). access ("hasRole ('DOCTOR')");
    }
}

Класс CustomUserDetailsService для справки, если требуется:

@Service
public class CustomUserDetailsService implements UserDetailsService {

    @Autowired
    private UsersRepository userRepository;

    @Override
    public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {

        Optional<Users> usersOptional = userRepository.findByEmail(email);

        Users user = null;

        if(usersOptional.isPresent()) {
            System.out.println(usersOptional.isPresent());
            user = usersOptional.get();
        }else {
            throw new RuntimeException("Email is not registered!");
        }

        return new CustomUserDetails(user);
    }

}

Как мне кажется, сервер должен проверять только действительность токена обновления, поскольку мы не передаем данные пользователя с токеном обновления,Так что я не знаю, почему это вообще требует userDetails.

Пожалуйста, помогите и сообщите, если я что-то упустил!Заранее спасибо.

1 Ответ

0 голосов
/ 04 февраля 2019

Я не уверен.Но, как я вижу, ваш код в WebSecurityConfiguration может быть подключен по умолчанию InMemoryUserDetailsManager UserDetailsService. Это может быть причиной, по которой у вас есть 2 разных поставщика.В одном вы пишете, в другом вы читаете пользователей.Пожалуйста, попробуйте изменить свой код, как показано ниже, и дайте мне знать, если это поможет:

Было:

@Autowired
    private UserDetailsService customUserDetailsService;

Мое видение, каким должно быть:

@Autowired
   private CustomUserDetailsService customUserDetailsService;
...