Tomcat重启后,Spring Security主体未完全填充

Ben*_*n J 3 java spring spring-security

我的问题很简单,在服务器重启(我自己的本地Tomcat)之后,Spring Security主体对象将重新填充每个字段(用户名,密码,电子邮件,用户类型等),用户ID字段除外.

我有以下User对象,它实现了Spring的UserDetails对象,并且还扩展了我自己的基础对象类:

public class User extends BaseDomainObject implements UserDetails {
    private String username;
    private String emailAddress;
    private String password;
    // ... etc ... /
}
Run Code Online (Sandbox Code Playgroud)

(仅供参考,User类有一个构造函数,它接受除ID之外的所有字段(由hibernate偷偷注入).此对象上没有setter.不确定这是否重要.)

用户ID字段位于BaseDomainObject中:

class BaseDomainObject {
    protected Long id;
    public Long getId() {
        return id;
    }
}
Run Code Online (Sandbox Code Playgroud)

成功登录后,主体将填充上述用户详细信息(包括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'
Run Code Online (Sandbox Code Playgroud)

但是,在服务器重新启动后,相同的日志输出如下所示:

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'
Run Code Online (Sandbox Code Playgroud)

我应该重申,User类(不在基类中)还有其他字段也已成功填充.基本上除ID外的一切.

Spring安全性在设置字段时是否会调用User构造函数?不可否认,我从来没有真正想过"如何"春天重新填充其他领域 - 也许这是我的问题?我真的不想在构造函数中用setter /公开ID字段.实际上,向构造函数添加ID不会执行任何操作.

谢谢你的帮助.

mat*_*t b 7

我建议确保你的两个域对象implements Serializable,否则servlet容器可能会选择不将它们序列化到磁盘(这是重启后会话数据重新填充的方式 - Tomcat正在读取序列化为文件的会话数据).

  • 更多细节:查看SecurityContextPersistenceFilter类,它定义了如何填充SecurityContextHolder.如果您正在使用HttpSessionSecurityContextRepository,那么用户的安全上下文(成功验证后由Spring分配的内容)将存储在HTTP会话中.如果您的servlet容器持续存在会话并在重新启动后恢复它们,那么您应该检查那里. (3认同)