我对Spring和Spring Security都是新手。我在读关于Spring Security的文章,它提出了principal的概念,应该是当前登录的用户。但如果我们有多个当前登录用户呢?那么,我的问题是,在Spring安全中,校长到底是什么?
例如,我已经阅读了本教程:
http://www.mkyong.com/spring-security/get-current-logged-in-username-in-spring-security/
而且他们似乎考虑到只有一个当前登录的用户,而这种情况并不常见。
如何检索特定用户?我如何区分正在处理请求的用户?
主体是当前登录的用户。但是,您可以通过绑定到当前线程的安全上下文来检索它,因此它也绑定到当前请求及其会话。
SecurityContextHolder.getContext()
在内部通过ThreadLocal
变量获取当前SecurityContext
实现。因为请求绑定到单个线程,这将为您获取当前请求的上下文。
为了简化,可以说安全上下文位于会话中,包含用户/主体和角色/权限。
如何检索特定用户?
你没有。所有的API都是为允许用户访问而设计的
以及如何区分正在执行请求的用户?
您不必这样做,这就是Servlet容器为您所做的。
委托人的简要定义:
主体代表用户的身份。
它可以是在简单级别上具有用户名的字符串对象,也可以是复杂的UserDetails对象。
校长只是JavaSE 6的旧接口。
作为没有默认实现的所有接口,它简单地定义了一些需要由将实现该接口的类实现的方法。
这些方法是
boolean equals(Object another)
Compares this principal to the specified object.
String getName()
Returns the name of this principal.
int hashCode()
Returns a hashcode for this principal.
String toString()
Returns a string representation of this principal.
正如Java文档所述:
这个接口表示主体的抽象概念,可以用来表示任何实体,例如个人、公司和登录id。
简单地说,它的使用只是为了让实现者实现这个接口,使一个实体在其他实体之间有唯一的区别。另外,getName()
必须返回一个值,根据该值,一个特定实体被唯一标识,并且不会与其他实体发生冲突。因此,如果使用的Principal
类型为UserDetails
,那么Principal
的getName()
返回UserDetails
的用户名。
如果我们看到Spring用于AbstractAuthenticationToken的实现。类
:
public String getName() {
if (this.getPrincipal() instanceof UserDetails) {
return ((UserDetails)this.getPrincipal()).getUsername();
} else if (this.getPrincipal() instanceof AuthenticatedPrincipal) {
return ((AuthenticatedPrincipal)this.getPrincipal()).getName();
} else if (this.getPrincipal() instanceof Principal) {
return ((Principal)this.getPrincipal()).getName();
} else {
return this.getPrincipal() == null ? "" : this.getPrincipal().toString();
}
}
还有一点很重要:
抽象类AbstractAuthenticationToken实现身份验证
和
接口身份验证扩展了主体
Principal
接口还确保实现者将实现equals()
和hashCode()
,这很有意义,因为代表组织、公司或个人的主体实体必须有某种方式与其他实体进行比较。