1

私は安らかな API を実装し、リソース所有者のパスワード資格情報付与で春のセキュリティ oauth を使用します。APIでセッションを使用したくないので、ユーザーがAPIを呼び出すたびにデータベースからトークンをチェックします。

認証されたユーザーが API を呼び出す場合 (たとえば、URI GET /users を使用)、現在のユーザーから userId を取得して、ビジネス サービスを操作する必要があります。私のビジネス サービスは、userName ではなく userId を使用して動作し、現在のユーザー情報を取得したり、現在のユーザーが何らかの操作を実行できるかどうかを確認したりできます。

現時点では、ユーザー名をトークンとともに保存します(全体JdbcTokenStore)。したがって、保存されているuserNameを使用して、毎回データベースからuserIdを取得できます。しかし、このソリューションは重すぎるため、サービスを使用する前に (トークンとユーザーのために) データベースに 2 回アクセスする必要があり、パフォーマンスが低下します。

したがって、この問題を解決するには、userId をトークンと共に保存します。このソリューションでは、データベースからトークンを取得すると、現在の userId があり、これを使用してサービスを直接呼び出すことができます。

問題は、カスタム トークン エンハンサーをデフォルトのトークン サービスに設定できないことです。

OAuth2ServerConfigurerAdapter を拡張する securityConfig での私の実装は次のとおりです。

    @Override
protected void configure(AuthenticationManagerBuilder authManagerBuilder) throws Exception {
    authManagerBuilder
    .userDetailsService(new CustomUserDetailsService(userService))
    .passwordEncoder(passwordEncoder())
        .and()
    .apply(new InMemoryClientDetailsServiceConfigurer())
        .withClient("ios-app")
        .resourceIds(RESOURCE_ID)
    .scopes("read", "write")
    .authorities("ROLE_USER")
    .authorizedGrantTypes("password")
    .secret("123456");
}

@Override
protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable();
        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
        http.requestMatchers()
        .and()
        .authorizeRequests()
        .antMatchers("users/create").permitAll()
        .anyRequest().authenticated()
        .and()
        .apply(new OAuth2ServerConfigurer())
        .tokenStore(new JdbcTokenStore(dataSource))
        .resourceId(RESOURCE_ID);
    }

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

カスタム トークン エンハンサーを追加するためのオーバーライドは次のtokenService()とおりですが、機能しません。

    @Override
public AuthorizationServerTokenServices tokenServices() throws Exception {
    DefaultTokenServices tokenService = (DefaultTokenServices)tokenServices();
    tokenService.setTokenEnhancer(new CustomTokenEnhancer());
    return tokenService;
}

そうでなければ、誰かがそれを行う考えを持っていますか?

4

0 に答える 0