Поток учетных данных клиента Oauth2 + бросание Spring Boot2 Нет сопоставленного PasswordEncoder> для ошибки «null» для идентификатора

Я обновляю свои существующие клиентские учетные данные Oauth2, чтобы использовать весеннюю загрузку 2.
Сервер авторизации использует базовую аутентификацию с кодировкой Base64(client:secret)
. Я использую RedisTokenStore для хранения токенов.

У меня возникают проблемы с конфигурацией, необходимой для конфигурации Oauth2 с новым обновлением. Я не смог найти надлежащую документацию, которая указывает мне на поток учетных данных клиента.
С обновлениями Spring 5 Security кодировка пароля не работает, я получаю :-

java.lang.IllegalArgumentException: There is no PasswordEncoder mapped for the id "null" error

Ниже приведена моя конфигурация: -

@Configuration
public class WebConfiguration extends WebSecurityConfigurerAdapter {

        @Override
        protected void configure(HttpSecurity http) throws Exception {
                http.
                        csrf().disable().
                        authorizeRequests().antMatchers(HttpMethod.OPTIONS, "/oauth/token").permitAll();
        }

}

Сервер авторизации и Ресурссервер

@Configuration
@EnableAuthorizationServer
public class Oauth2Configuration extends AuthorizationServerConfigurerAdapter {

    @Autowired
    private ClientDetailsService clientDetailsService;

    @Autowired
    private JedisConnectionFactory jedisConnFactory;

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.withClientDetails(clientDetailsService);
    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints.tokenStore(tokenStore());
        super.configure(endpoints);
    }

    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
        security.passwordEncoder(passwordEncoder());
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        String idForEncode = "bcrypt";
        Map<String, PasswordEncoder> encoderMap = new HashMap<>();
        encoderMap.put(idForEncode, new BCryptPasswordEncoder());
        return new DelegatingPasswordEncoder(idForEncode, encoderMap);
    }

    @Bean
    public TokenStore tokenStore() {
        return new Oauth2TokenStore(jedisConnFactory);
    }

    @Configuration
    @EnableResourceServer
    protected static class ResourceServer extends ResourceServerConfigurerAdapter {

        @Override
        public void configure(HttpSecurity http) throws Exception {
            http
                    .authorizeRequests()
                    .antMatchers("/verify_token").authenticated()
                    .antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
                    .antMatchers(HttpMethod.GET, "/info").permitAll()
                    .antMatchers(HttpMethod.GET, "/health").permitAll();
        }
    }
}

RedisTokenStore

public class Oauth2TokenStore extends RedisTokenStore {
    @Autowired
    private ClientDetailsService clientDetailsService;


    public Oauth2TokenStore(RedisConnectionFactory connectionFactory) {
        super(connectionFactory);
    }

    @Override
    public void storeAccessToken(OAuth2AccessToken token, OAuth2Authentication authentication) {
        Object principal = authentication.getPrincipal();

        //Principal is consumer key since we only support client credential flow
        String consumerKey = (String) principal;

        //get client detials
        ClientDetails clientDetails = clientDetailsService.loadClientByClientId(consumerKey);


        // Logic to Create JWT
        .
        .
        .
        //Set it to Authentication
        authentication.setDetails(authToken);

       super.storeAccessToken(token, authentication);
    }

    @Override
    public OAuth2Authentication readAuthentication(String token) {
        OAuth2Authentication oAuth2Authentication =  super.readAuthentication(token);
        if (oAuth2Authentication == null) {
            throw new InvalidTokenException("Access token expired");
        }
        return oAuth2Authentication;
    }
}
}

Также нужно ли мне кодировать токен, когда я сохраняю его в магазине Redis после обновления весенней кодировки пароля безопасности?

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
0
865
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Эта ошибка означает, что сохраненный пароль не имеет префикса с типом пароля.

Например, ваши хешированные пароли могут выглядеть примерно так:

$2a$10$betZ1XaM8rTUQHwWS.cyIeTKJySBfZsmC3AYxYjwa4fHtr6i/.9oG

Но теперь Spring Security ожидает:

{bcrypt}$2a$10$betZ1XaM8rTUQHwWS.cyIeTKJySBfZsmC3AYxYjwa4fHtr6i/.9oG

У вас в основном есть два варианта. Во-первых, настроить DelegatingPasswordEncoder то, что должно быть по умолчанию:

@Bean
public PasswordEncoder passwordEncoder() {
    String idForEncode = "bcrypt";
    BCryptPasswordEncoder bcrypt = new BCryptPasswordEncoder();
    Map<String, PasswordEncoder> encoderMap = 
        Collections.singletonMap(idForEncode, bcrypt);
    DelegatingPasswordEncoder delegating =
        new DelegatingPasswordEncoder(idForEncode, encoderMap);
    delegating.setDefaultPasswordEncoderForMatches(bcrypt);
    return delegating;
}

Или, во-вторых, сделать пакетное обновление хранилища паролей (с префиксом {bcrypt}).

Я не уверен, откуда ваш ClientDetailsService тянет, но я бы начал искать там.

ОБНОВИТЬ: это предполагает, однако, что ваши существующие пароли зашифрованы. Если это не так, вы должны предоставить любой соответствующий кодировщик:

@Bean
public PasswordEncoder passwordEncoder() {
    String idForEncode = "bcrypt";
    PasswordEncoder existing = new MyPasswordEncoder();
    PasswordEncoder updated = new BCryptPasswordEncoder();
    Map<String, PasswordEncoder> encoderMap = 
        Collections.singletonMap(idForEncode, updated);
    DelegatingPasswordEncoder delegating =
        new DelegatingPasswordEncoder(idForEncode, encoderMap);
    delegating.setDefaultPasswordEncoderForMatches(existing);
    return delegating;
}

спасибо за вашу помощь, clientId и секрет генерируются другой службой, которая не является частью этого приложения, и это общедоступный API, поэтому нам нужно поделиться clientId и секретом в открытом тексте с запрашивающим приложением. Я думаю, вы правы, мне нужно изменить хранилище, чтобы добавить {bcrypt}, я не смог запустить его с помощью PasswordEncoder, которым вы поделились, он говорит Encoded password does not look like BCrypt, я попробовал NoOpPasswordEncoder.getInstance() и запустил его.

cheddarDev 20.02.2019 20:20

Какой хэш вы используете для своих паролей? Ошибка означает, что кодировщик считает, что это не bcrypt.

jzheaux 20.02.2019 20:25

Я храню его в виде открытого текста, в ключе клиента или секрете клиента нет хэша, формат Base64 encode of client:secret

cheddarDev 20.02.2019 20:27

до обновления он использовал PlaintextPasswordEncoder.

cheddarDev 20.02.2019 20:30

Итак, почему бы просто не вернуть экземпляр PlaintextPasswordEncoder, OOC?

jzheaux 20.02.2019 20:39

Я не могу, так как это больше не часть весны 5.

cheddarDev 20.02.2019 20:47

Другие вопросы по теме