我的问题很简单,在服务器重启(我自己的本地Tomcat)之后,Spring Security主体对象将重新填充每个字段(用户名,密码,电子邮件,用户类型等),除了用户ID字段。
我有以下User对象,它实现了Spring的UserDetails对象,并且还扩展了我自己的基础对象类:
public class User extends BaseDomainObject implements UserDetails {
private String username;
private String emailAddress;
private String password;
// ... etc ... /
}
(仅供参考,User类有一个构造函数,它接受除ID之外的所有字段(由hibernate偷偷注入)。此对象上没有setter。不确定这是否重要。)
用户ID字段位于BaseDomainObject:
中class BaseDomainObject {
protected Long id;
public Long getId() {
return id;
}
}
成功登录后,主体将填充上述用户详细信息(包括ID),一切都很满意。这由以下日志输出(包括User [id,username,emailAddress]形式的上述User类的toString表示)确认:
2011-07-26 11:50:25,188 DEBUG [org.springframework.security.web.context.HttpSessionSecurityContextRepository] - Obtained a valid SecurityContext from SPRING_SECURITY_CONTEXT: 'org.springframework.security.core.context.SecurityContextImpl@5e8fac5a: Authentication: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@5e8fac5a: Principal: User[1,test,test@test.com]; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@255f8: RemoteIpAddress: 0:0:0:0:0:0:0:1%0; SessionId: 450FFF87C04098ECC58C2E0829D21D69; Granted Authorities: ROLE_USER, ROLE_CUSTOMER'
但是,在服务器重新启动后,相同的日志输出如下所示:
2011-07-26 11:52:28,355 DEBUG [org.springframework.security.web.context.HttpSessionSecurityContextRepository] - Obtained a valid SecurityContext from SPRING_SECURITY_CONTEXT: 'org.springframework.security.core.context.SecurityContextImpl@729a68c9: Authentication: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@729a68c9: Principal: User[null,test,test@test.com]; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@255f8: RemoteIpAddress: 0:0:0:0:0:0:0:1%0; SessionId: 450FFF87C04098ECC58C2E0829D21D69; Granted Authorities: ROLE_USER, ROLE_CUSTOMER'
我应该重申,User类(不在基类中)还有其他字段也已成功填充。基本上除ID外的一切。
Spring安全性在设置字段时是否会调用User构造函数?不可否认,我从来没有真正想过“如何”春天重新填充其他领域 - 也许这是我的问题?我真的不想在构造函数中用setter /公开ID字段。实际上,向构造函数添加ID不会做任何事情。
感谢您的帮助。
答案 0 :(得分:7)
我建议确保你的两个域对象implements Serializable
,否则servlet容器可能会选择不将它们序列化到磁盘(这是重启后会话数据的重新填充方式 - Tomcat正在读取会话数据序列化为文件)。