1

我实现了一个restful API,并使用了spring security oauth和资源所有者密码凭证授权。我想避免在 API 中使用会话,所以每次用户调用 API 时我都会从数据库中检查令牌。

当经过身份验证的用户调用 API(例如使用 URI GET /users)时,我需要从当前用户获取 userId 以使用我的业务服务。我的业务服务使用 userId 而不是 userName,并允许我检索当前用户信息或检查当前用户是否被允许执行某些操作。

目前,我将用户名与令牌(跨JdbcTokenStore)一起存储。所以我可以每次使用存储的用户名从数据库中检索用户 ID。但是这个解决方案太重了,它迫使我在使用对性能来说太糟糕的服务之前访问数据库两次(对于令牌和用户)。

因此,为了解决这个问题,我想将 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