我对Spring和Spring Security真的很陌生。我在阅读有关Spring Security的内容,它提出了 principal 的概念,它应该是当前登录的用户。但是如果我们有多个当前登录的用户呢?所以,我的问题是,Spring Security中的principal到底是什么?
我读过这个教程的例子:
http://www.mkyong.com/spring-security/get-current-logged-in-username-in-spring-security/
他们似乎考虑到只有一个当前登录的用户,这是不常见的情况。
如何检索特定的用户?如何区分正在执行请求的用户?
3条答案
按热度按时间rdlzhqv91#
主体 * 是 * 当前登录的用户。但是,您通过绑定到当前线程的安全上下文检索它,因此,它也绑定到当前请求及其会话。
SecurityContextHolder.getContext()
通过一个ThreadLocal
变量在内部获取当前SecurityContext
的实现。由于一个请求绑定到一个线程,这将为您获取 * 当前请求 * 的上下文。为了简化,可以说安全上下文在会话中,包含用户/主体和角色/权限。
如何检索特定用户?
所有的API都被设计成允许访问 * 当前请求 * 的用户和会话。
假设用户A是当前100个经过身份验证的用户之一。如果A向您的服务器发出请求,服务器将分配一个线程来处理该请求。如果您执行
SecurityContextHolder.getContext().getAuthentication()
,则您在此线程的上下文中执行此操作。从该线程中,您无法访问由另一个线程处理的用户B的上下文。如何区分正在执行请求的用户?
您不必这样做,这就是Servlet容器为您做的事情。
6xfqseft2#
委托人的简要定义:
Principal代表用户的身份。
它可以是一个String对象,在简单级别上具有username,也可以是一个复杂的UserDetails对象。
kdfy810k3#
Principal只是Java SE 6中的一个旧接口。
由于所有接口都没有默认实现**它很简单 * 定义了一些方法 ,这些方法需要由将实现该接口的类实现*。
这些方法
字符串
正如Java Doc所说:
这个接口表示主体的抽象概念,它可以用来表示任何实体,比如个人、公司和登录ID。
简单地说,它只是用来实现这个接口,使一个实体在其他实体之间唯一地嵌套。另外,
getName()
必须返回一个值,通过该值可以唯一地标识一个特定的实体,并且不会与其他实体冲突。因此,如果使用的Principal
是UserDetails
类型,那么getName()
的Principal
返回UserDetails
的UserName
。如果我们看到Spring为
AbstractAuthenticationToken.class
使用的实现:型
还必须提到:
abstract class AbstractAuthenticationToken implements Authentication
和interface Authentication extends Principal
个Principal
接口还确保实现者将实现equals()
和hashCode()
,这很有意义,因为代表组织或公司或个人的主体实体必须有某种方式与其他实体进行比较。