提问者:小点点

Spring安全的“原则”是什么?


我对Spring和Spring Security都是新手。我在读关于Spring Security的文章,它提出了principal的概念,应该是当前登录的用户。但如果我们有多个当前登录用户呢?那么,我的问题是,在Spring安全中,校长到底是什么?

例如,我已经阅读了本教程:

http://www.mkyong.com/spring-security/get-current-logged-in-username-in-spring-security/

而且他们似乎考虑到只有一个当前登录的用户,而这种情况并不常见。

如何检索特定用户?我如何区分正在处理请求的用户?


共3个答案

匿名用户

主体是当前登录的用户。但是,您可以通过绑定到当前线程的安全上下文来检索它,因此它也绑定到当前请求及其会话。

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,那么PrincipalgetName()返回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(),这很有意义,因为代表组织、公司或个人的主体实体必须有某种方式与其他实体进行比较。