使用Spring Security OAuth2,在TokenStore中刷新存储的身份验证的正确方法是什么?

Joe*_*Joe 5 java oauth spring-security

我们正在使用资源所有者凭据授权类型(使用oauth2:passwordin security-config.xml.让我们播放这个场景来解释我的困境:

  1. 鲍勃是由当局创建的 ROLE_USER
  2. Bob尝试访问受oauth2保护的资源
  3. Bob使用官方移动应用程序访问它,因此客户端凭据是正确的
  4. 鲍勃的访问令牌创建并存储在TokenStore,键入他的username,client_idscope.(请参阅DefaultAuthenticationKeyGenerator.java)
  5. 鲍勃的电话试图与此访问令牌来调用受保护的服务,但是这些服务需要用户拥有一个authorityROLE_MOBILE_USER.
  6. Bob联系数据库所有者并已ROLE_MOBLE_USER添加到数据库中的用户.
  7. Bob尝试获取另一个访问令牌,但是DefaultTokenServices返回相同的非工作访问令牌.
  8. 利用他的新authority功能的唯一方法是等到他的旧访问令牌到期,这样他就可以获得一个正确的新访问令牌authority.

有很多方法可以解决这个问题.

例如,添加ROLE_MOBILE_USER到Bob的权限的管理应用程序可以清除数据库中的所有访问令牌和授权.通过这种方式,DefaultTokenServices只需创建一个新的,将正确的权限序列化为新的OAuth2Authentication.但是,我们可能不希望管理Web应用程序此时关注OAuth(至少现在还没有).如果可能的话,我们希望尽可能简洁地保持管理应用程序的关注,而且现在对oauth没有任何依赖性.

我们可以将DELETE方法公开给/oauth/access_token端点,并告诉移动应用程序尝试删除该访问令牌并重新请求一个,以防存储authorities过时.这感觉更像是一种解决方法.

最后我可以authorities在我自己定义的序列化中AuthenticationKeyGenerator.它基本上会使用username,client_id,scope,和authorities授权,并对其执行相同的摘要算法.这样,当Bob尝试登录时,他将获得相同的访问令牌,但底层令牌存储将识别出他具有不同的身份验证(来自令牌granter bean中的身份验证管理器)并刷新其数据库.我有这个解决方案的问题是,它只是依赖于底层令牌存储装置的实施行为(尽管都InMemoryTokenStoreJdbcTokenStore这样的行为).

你能想到更好/更清洁的解决方案吗?我是在想这个吗?

提前致谢.

Sco*_*ard 2

我通过在发送身份验证信息时删除给定用户的所有令牌来解决我的应用程序中的此问题。

使用自定义 AuthenticationProvider bean。

@Component("authenticationProvider")
public class AuthenticationProviderImpl implements AuthenticationProvider
Run Code Online (Sandbox Code Playgroud)

在令牌存储 bean 中自动装配。

@Autowired
@Qualifier("tokenStore")
private TokenStore tokenStore;
Run Code Online (Sandbox Code Playgroud)

然后,在身份验证方法中,如果第二次传递凭据,则删除给定用户的所有令牌。

@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
    UsernamePasswordAuthenticationToken token = (UsernamePasswordAuthenticationToken) authentication;

    try {
         //Do authentication

        //Delete previous tokens
        Collection<OAuth2AccessToken> tokenCollection = tokenStore.findTokensByUserName(token.getName());
        for (OAuth2AccessToken oToken : tokenCollection){
            tokenStore.removeAccessToken(oToken);
        }

        //return Authentication;
    }
}
Run Code Online (Sandbox Code Playgroud)

大多数请求将使用令牌并完全绕过它,但是当传递凭据时,将生成一个新令牌。该令牌将与新的身份验证对象相关联,该对象将包括所有新角色以及对用户所做的更改。