Ошибка Oauth 2.0 при переходе с весенней загрузки версии 1.5.7 на 2.0, работала нормально на 1.5.7.RELEASE - PullRequest
1 голос
/ 05 ноября 2019

Я реализовал Oauth в Spring Boot 1.5.7, но когда я переключился на 2, он показал мне ошибку "java.lang.IllegalArgumentException: не существует сопоставленного PasswordEncoder для идентификатора" null ".

Из некоторыхВ ходе исследования я обнаружил, что это может быть проблема с хранением пароля и его кодировкой.

То, что я пробовал - я пытался зашифровать секрет клиента в файле сервера авторизации, но ничего не происходит, и ошибкаостается.

Я также пытался сохранить пароль с {bcrypt} в качестве префикса, поскольку Spring Security 5 ищет ann {id} во время поиска пароля.

Я не могуИзвлеките токен доступа, и вышеуказанная ошибка не исчезла. Может кто-нибудь помочь мне разобраться в этом? Я прочитал и реализовал почти все, и это, похоже, не работает.

Обновление: Мне удалось устранить вышеуказанную ошибку, сохранив пароль в формате {bcrypt}. Аналогичным образом применив passwordEncoder в других необходимых местах.

Проблема: Я сейчас нахожусьошибка с неверными учетными данными. Я отладил и понял, что мы не получаем имя пользователя, которое мы пытаемся передать в API, и получаем нулевой параметр. Поток достигает userDetailservice, но с параметром epmty. Я приложил свой UserDetailsService вместе с этим.

SecurityConfig.java

@Configuration
@EnableWebSecurity
public class OAuth2SecurityConfiguration extends WebSecurityConfigurerAdapter {

  @Autowired
  private ClientDetailsService clientDetailsService;

  @Autowired
  private UserDetailsService userDetailsService;

  @Autowired
  private CustomPasswordEncoder customPasswordEncoder;

  @Autowired
  public void globalUserDetails(AuthenticationManagerBuilder auth) throws Exception {
    auth.userDetailsService(userDetailsService).passwordEncoder(customPasswordEncoder);
  }

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

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

  @Bean
  @Autowired
  public TokenStoreUserApprovalHandler userApprovalHandler(TokenStore tokenStore) {
    TokenStoreUserApprovalHandler handler = new TokenStoreUserApprovalHandler();
    handler.setTokenStore(tokenStore);
    handler.setRequestFactory(new DefaultOAuth2RequestFactory(clientDetailsService));
    handler.setClientDetailsService(clientDetailsService);
    return handler;
  }

  @Bean
  @Autowired
  public ApprovalStore approvalStore(TokenStore tokenStore) throws Exception {
    TokenApprovalStore store = new TokenApprovalStore();
    store.setTokenStore(tokenStore);
    return store;
  }

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

AuthorizationServerConfig.java

@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {

    private static String REALM = "api-security";

    @Value("${app.oauth.client-id}")
    private String CLIENT_ID;

    @Value("${app.oauth.client-secret}")
    private String CLIENT_SECRET;

    @Value("${app.oauth.access-token-validity}")
    private int accessTokenValidity;

    @Value("${app.oauth.refresh-token-validity}")
    private int refreshTokenValidity;

    @Autowired
    @Qualifier("tokenStore")
    private TokenStoreService tokenStore;

    @Autowired
    private UserApprovalHandler userApprovalHandler;

    @Autowired
    private BCryptPasswordEncoder passwordEncoder;

    @Autowired
    @Qualifier("authenticationManagerBean")
    private AuthenticationManager authenticationManager;

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory().withClient(CLIENT_ID)
                .authorizedGrantTypes("password", "authorization_code", "refresh_token", "implicit")
                .authorities("ROLE_ADMIN").scopes("read", "write", "trust").secret(passwordEncoder.encode(CLIENT_SECRET))
                .accessTokenValiditySeconds(accessTokenValidity).refreshTokenValiditySeconds(refreshTokenValidity);
        System.out.println(passwordEncoder.encode(CLIENT_SECRET));
        System.out.println(CLIENT_SECRET);
    }

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

    @Override
    public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
        oauthServer.realm(REALM + "/client");
    }
}

UserDetailsService.java

@Configuration
@EnableWebSecurity
public class OAuth2SecurityConfiguration extends WebSecurityConfigurerAdapter {

  @Autowired
  private ClientDetailsService clientDetailsService;

  @Autowired
  @Qualifier("userDetailsService")
  private UserDetailsService userDetailsService;


  @Autowired
  public void globalUserDetails(AuthenticationManagerBuilder auth) throws Exception {
    auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
  }

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

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

  @Bean
  @Autowired
  public TokenStoreUserApprovalHandler userApprovalHandler(TokenStore tokenStore) {
    TokenStoreUserApprovalHandler handler = new TokenStoreUserApprovalHandler();
    handler.setTokenStore(tokenStore);
    handler.setRequestFactory(new DefaultOAuth2RequestFactory(clientDetailsService));
    handler.setClientDetailsService(clientDetailsService);
    return handler;
  }

  @Bean
  @Autowired
  public ApprovalStore approvalStore(TokenStore tokenStore) throws Exception {
    TokenApprovalStore store = new TokenApprovalStore();
    store.setTokenStore(tokenStore);
    return store;
  }

  @Bean
  public PasswordEncoder passwordEncoder() {
      return PasswordEncoderFactories.createDelegatingPasswordEncoder();
  }

//  @Bean
//  @Override
//  public UserDetailsService userDetailsServiceBean() throws Exception {
//      return super.userDetailsServiceBean();
//  }

//  @Bean
//  public UserDetailsService userDetailsService() {
//    return super.userDetailsService();
//  }
}

1 Ответ

0 голосов
/ 07 ноября 2019

Для тех, кто сочтет это полезным, я смог решить эту проблему следующим образом:

  1. Если вы очистите свою коллекцию токенов доступа или таблицу, вы сможете получитьТок доступа один раз, но это все. Каждый последующий запрос будет сопровождаться «Ошибка 500 - Внутренняя ошибка сервера».

  2. Это происходит потому, что весенняя загрузка не смогла понять токен доступа из БД при выполнении других запросов, для которых вы можете использовать пакет "org.springframework.util.SerializationUtils". Вы можете выполнить поиск по этому вопросу, он сериализует и десериализует токены доступа и обновляет токен при выполнении запросов.

...