OAuth2 с асимметричным подходом

#java #spring #spring-boot #spring-security #oauth-2.0

#java #весна #весенняя загрузка #spring-безопасность #oauth-2.0

Вопрос:

Я внедрил сервер ресурсов и сервер авторизации с помощью spring cloud oauth2. Когда я реализовал приложение OAuth с использованием подхода по умолчанию (без использования асимметричного или симметричного подхода), токен по умолчанию генерируется сервером авторизации, и когда мне нужно связаться с сервером ресурсов и сервером авторизации, тогда в файле конфигурации сервера ресурсов можно использовать следующие свойства.

ресурс-server.yml со значением по умолчанию

 security:
  oauth2:
    client:
      client-id: web
      client-secret: *****
    resource:
      token-info-uri: "http://localhost:9092/oauth/check_token"
  

Когда я использую асимметричный подход для подписи токена закрытым ключом на сервере авторизации и использую открытый ключ для проверки токена на сервере ресурсов со следующим свойством security:jwt:public-key: classpath:public.txt , при вызове ресурса с сервера ресурсов возникает следующий несанкционированный ответ.

ресурс-server.yml с асимметричным

 security:
  jwt:
    public-key: classpath:public.txt
  

Конечная точка API

 http://localhost:9090/user?Authorization=bearer **********
  

Ответ

 {
"error": "invalid_token",
"error_description": "Cannot convert access token to JSON"
}
  

Примечание — когда я использую client token-info-uri свойства и с асимметричным подходом в resource-server.yml, возникает следующая ошибка.

 Method springSecurityFilterChain in org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration required a single bean, but 2 were found:
    - tokenServices: defined by method 'tokenServices' in class path resource [com/benz/resource/api/config/ResourceServerConfiguration.class]
    - remoteTokenServices: defined by method 'remoteTokenServices' in class path resource [org/springframework/boot/autoconfigure/security/oauth2/resource/ResourceServerTokenServicesConfiguration$RemoteTokenServicesConfiguration$TokenInfoServicesConfiguration.
  

Я должен прояснить следующий вопрос

  1. Без использования token-info-uri client свойств и как сервер ресурсов идентифицирует конкретный сервер авторизации ?.

  2. почему произошла несанкционированная ошибка (о которой упоминалось выше)?

Класс ResourceServerConfig

 @Configuration
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {

    @Value("${security.jwt.public-key}")
    private Resource publicKey;

    private TokenStore tokenStore;


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

    @Bean
    public DefaultTokenServices tokenServices(TokenStore tokenStore)
    {
        DefaultTokenServices tokenServices=new DefaultTokenServices();
        tokenServices.setTokenStore(tokenStore);
        return tokenServices;
    }

    @Bean
    public TokenStore tokenStore() throws Exception
    {
        if(tokenStore==null)
            tokenStore=new JwtTokenStore(tokenConverter());

        return tokenStore;
    }

    private JwtAccessTokenConverter tokenConverter() throws Exception
    {
        JwtAccessTokenConverter converter=new JwtAccessTokenConverter();
        converter.setVerifierKey(getPublicKeyAsString());
        return converter;
    }


    private String getPublicKeyAsString() throws Exception
    {
        return IOUtils.toString(publicKey.getInputStream(),UTF_8);
    }
}
  

Ссылка на Github для

ресурс-сервер-реализация

авторизация-сервер-реализация

Если вам нужна более подробная информация, пожалуйста, прокомментируйте это, тогда я смогу обновить

Ответ №1:

Я решил проблему. В моем случае tokenConverter метод вызывается во время JwtTokenStore создания экземпляра компонента. Я изменил подход к созданию экземпляра JwtAccessTokenConverter компонента отдельно, добавив аннотацию @Bean . В этом случае он работает без каких-либо перерывов.

     @Bean
    public JwtAccessTokenConverter tokenConverter() throws Exception
    {
        JwtAccessTokenConverter converter=new JwtAccessTokenConverter();
        converter.setVerifierKey(getPublicKeyAsString());
        return converter;
    }