我们正在使用资源所有者凭证授权类型(使用oauth2:password
in security-config.xml
。让我们播放这个场景来解释我的困境:
- Bob 是由当局创建的
ROLE_USER
- Bob 尝试访问受 oauth2 保护的资源
- Bob 使用官方移动应用程序访问它,因此客户端凭据是正确的
- Bob 的访问令牌被创建并存储在 中
TokenStore
,键入他的username
、client_id
和scope
。(参见DefaultAuthenticationKeyGenerator.java) - Bob 的电话尝试使用此访问令牌调用受保护的服务,但这些服务要求用户
authority
拥有ROLE_MOBILE_USER
. - Bob 联系了数据库所有者,并
ROLE_MOBLE_USER
在数据库中添加了他的用户。 - Bob 尝试获取另一个访问令牌,但
DefaultTokenServices
返回给他的是相同的、无效的访问令牌。 - 利用他的新访问令牌的唯一方法
authority
是等到他的旧访问令牌过期,这样他就可以得到一个正确的新访问令牌authority
。
有很多方法可以解决这个问题。
一方面,添加ROLE_MOBILE_USER
到 Bob 权限的管理应用程序可以清除数据库中的所有访问令牌和授权。这样,DefaultTokenServices
将只创建一个具有正确权限的新权限,并将其序列化为他的新 OAuth2Authentication。但是,我们现在可能不希望 Administration webapp 关注 OAuth(至少现在还没有)。如果可能的话,我们希望管理应用程序的关注点尽可能简洁,并且现在不依赖于 oauth。
DELETE
我们可以将该方法暴露给/oauth/access_token
端点,并告诉移动应用程序尝试删除该访问令牌并重新请求一个,以防万一存储authorities
过时。不过,这感觉更像是一种解决方法。
最后我可以authorities
在我自己定义的AuthenticationKeyGenerator
. 它基本上会使用授权的 、 、 和 ,并对它们执行相同的username
摘要client_id
算法scope
。authorities
这样,当 Bob 尝试登录时,他将获得相同的访问令牌,但底层令牌存储将识别出他具有不同的身份验证(来自令牌授予者 bean 中的身份验证管理器)并刷新其数据库。我对这个解决方案的问题是它仅仅依赖于底层令牌存储的实现行为(尽管两者都InMemoryTokenStore
以JdbcTokenStore
这种方式运行)。
你能想到任何更好/更清洁的解决方案吗?这是我想太多了吗?
提前致谢。