私は安らかな 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;
}
そうでなければ、誰かがそれを行う考えを持っていますか?