【发布时间】:2015-09-08 23:58:06
【问题描述】:
我有一个与 AuthorizationToken 对象一对一关系的 User 对象。这个项目的基础可以找到here
当用户登录时,通过以一对一的方式保持与用户相关联的授权令牌创建一个新会话,并指定到期时间。出于开发目的,此到期时间设置为 1 个月,这在我的脑海中。现在我的令牌已经开始过期,系统出现错误。
用户登录时调用如下方法:
public AuthorizationToken createAuthorizationToken(User user) {
if(user.getAuthorizationToken() == null || user.getAuthorizationToken().hasExpired()) {
LOG.debug("UserToken has expired or is null, creating new token");
user.setAuthorizationToken(new AuthorizationToken(user, applicationConfig.getAuthorizationExpiryTimeInSeconds()));
userRepository.save(user);
}
return user.getAuthorizationToken();
}
这将返回当前令牌,如果它为空或过期,则返回一个新令牌。如果 null 或过期(setAuthorizationToken 方法),连接到用户的令牌也会被替换。这行得通,我的新令牌在数据库中创建并返回给客户端。
然后我们使用令牌为每个后续请求创建请求签名。服务器接收签名,使用存储的令牌进行复制并检查它们是否相同以识别发送者。
问题出在这里,下面是在服务器端创建签名的方法:
private boolean isAuthorized(User user, AuthorizationRequestContext authorizationRequest, String hashedToken) {
String unEncodedString = composeUnEncodedRequest(authorizationRequest);
AuthorizationToken authorizationToken = user.getAuthorizationToken();
String userTokenHash = encodeAuthToken(authorizationToken.getToken(), unEncodedString);
if (hashedToken.equals(userTokenHash)) {
return true;
}
return false;
}
我使用与原始登录过程相同的 user.getAuthorizationToken() 方法,但它产生两个不同的值。 login 方法返回新创建的令牌,签名服务返回数据库中与该用户相关的第一个实例(现在已过期,不应再映射到用户对象)。这里出了什么问题?是否只是清理过期令牌以免混淆的问题?我确信这是一个更深层次的问题,因为用户一次应该只有一个身份验证令牌映射。
感谢任何有关代码的 cmets。
【问题讨论】:
-
你是如何在用户中阅读并保持用于阅读用户的上下文的? EntityManager 是事务性上下文,并维护它们用于读取的托管实体的缓存。如果您保留它,则在其他上下文中所做的任何更改都不会在长期存在的 EntityManager 中可见,除非它们首先被清除或实体被刷新.
-
只是想补充一点,是的,这也是一个问题。将@Transactional 注释添加到该方法可确保将更改提交到数据库。 (repository.save 没有执行数据库提交)
标签: java hibernate session jpa