我实现了一个restful API,我使用spring security oauth和资源所有者密码凭据grant。 我想避免在API中使用会话,所以每次用户调用API时都会检查数据库中的令牌。
当经过身份验证的用户调用API时(例如使用URI GET / users),我需要从当前用户获取userId以使用我的业务服务。我的业务服务使用userId而不是userName,并允许我检索当前用户信息或检查当前用户是否允许执行某些操作。
目前,我使用令牌存储用户名(跨JdbcTokenStore
)。所以我每次都可以使用存储的userName从数据库中检索userId。但是这个解决方案太重了,它迫使我在使用对性能太糟糕的服务之前两次访问数据库(对于令牌和用户)。
所以要解决这个问题,我想用userId存储令牌。使用此解决方案,当我从数据库获取令牌时,我拥有当前的userId,我可以直接使用此服务调用该服务。
问题是我无法成功将自定义令牌增强器设置为默认令牌服务。
这是我在securityConfig中实现的扩展OAuth2ServerConfigurerAdapter的实现:
@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;
}
有没有人有这个想法呢?