简体   繁体   English

在 JSP EL 表达式中获取 Spring Security Principal

[英]Get Spring Security Principal in JSP EL expression

I am using Spring MVC and Spring Security version 3.0.6.RELEASE.我正在使用 Spring MVC 和 Spring Security 版本 3.0.6.RELEASE。 What is the easiest way to get the user name in my JSP?在我的 JSP 中获取用户名的最简单方法是什么? Or even just whether or not the user is logged in?或者甚至只是用户是否登录? I can think of a couple ways:我可以想到几种方法:

1. Using a scriptlet 1. 使用脚本

Using a scriptlet like this to determine if the user is logged in:使用这样的脚本来确定用户是否已登录:

<%=org.springframework.security.core.context.SecurityContextHolder.getContext()
    .getAuthentication().getPrincipal().equals("anonymousUser")
    ? "false":"true"%>

I'm not a fan of using scriptlets, though, and I want to use this in some <c:if> tags, which requires putting it back as a page attribute.不过,我不喜欢使用 scriptlet,我想在一些<c:if>标签中使用它,这需要将它作为页面属性放回去。

2. Using SecurityContextHolder 2. 使用 SecurityContextHolder

I could again use SecurityContextHolder from my @Controller and put it on the model.我可以再次使用@Controller SecurityContextHolder 并将其放在模型上。 I need this on every page, though, so I'd rather not have to add this logic in every one of my Controllers.不过,我在每一页都需要这个,所以我宁愿不必在我的每个控制器中添加这个逻辑。

I suspect there's a cleaner way to do this...我怀疑有一种更清洁的方法可以做到这一点......

Check Spring security tags : <sec:authentication property="principal.username" />检查 Spring 安全标签: <sec:authentication property="principal.username" />

http://static.springsource.org/spring-security/site/docs/3.0.x/reference/taglibs.html http://static.springsource.org/spring-security/site/docs/3.0.x/reference/taglibs.html

And you can check if logged :您可以检查是否已登录:

<sec:authorize access="isAuthenticated()"> 

instead of c:if而不是 c:if

I know there are other answers in the thread, but none have answered how you can check if user is authenticated.我知道线程中还有其他答案,但没有人回答如何检查用户是否已通过身份验证。 So I'm sharing what my code look likes.所以我要分享我的代码是什么样子的。

Include the tag lib in your project:在您的项目中包含标签库:

<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>

Then create a user object in current scope by adding:然后通过添加以下内容在当前范围内创建一个用户对象:

<sec:authentication var="user" property="principal" />

Then you can easily show the username by adding.然后您可以通过添加轻松显示用户名。 Remember the 'principal' object is generally of type string unless you have implemented the spring security in a way to change it to another Class in your project:请记住,'principal' 对象通常是字符串类型,除非您以某种方式实现了 spring 安全性,将其更改为项目中的另一个类:

<sec:authorize access="hasRole('ROLE_USER') and isAuthenticated()">
${user}
</sec:authorize>

I hope this helps somebody looking to check user roles.我希望这对希望检查用户角色的人有所帮助。

If you are using Maven, then add the dependency tag as mentioned by Christian Vielma in this thread.如果您使用的是 Maven,请添加 Christian Vielma 在此线程中提到的依赖项标记。

Thanks!谢谢!

You can use like this: Spring Security Tag Lib - 3.1.3.RELEASE你可以这样使用:Spring Security Tag Lib - 3.1.3.RELEASE

<sec:authentication var="principal" property="principal" />

and Then:接着:

${principal.username}

I was using Maven so I had to add the taglibs library adding this to the pom.xml我正在使用 Maven,所以我不得不添加 taglibs 库,将其添加到 pom.xml

<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-taglibs</artifactId>
    <version>3.1.3.RELEASE</version>
</dependency>

Then in my jsp added:然后在我的jsp中添加:

<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>

And:和:

<sec:authentication property="principal" />

principal.username kept giving me errors (maybe is the way I created the UsernamePasswordAuthenticationToken object, not sure). principal.username一直给我错误(也许是我创建UsernamePasswordAuthenticationToken对象的方式,不确定)。

I think <sec:authentication property="principal.username" /> will not always work because type returned by Authentication.getPrincipal() is Object, ie: it could be a UserDetail (for which the above will work), a String or anything else.我认为<sec:authentication property="principal.username" />并不总是有效,因为Authentication.getPrincipal()返回的类型是 Object,即:它可能是UserDetail (上面的方法适用)、String 或还要别的吗。

For purpose of displaying username in JSP page what I find more reliable is using ${pageContext.request.userPrincipal.name} .为了在 JSP 页面中显示用户名,我发现更可靠的是使用${pageContext.request.userPrincipal.name}

This uses java.security.Principal.getName() which returns String.这使用返回字符串的java.security.Principal.getName()

This works whether user is logged in or not, and works when using Anonymous Authentication:无论用户是否登录,这都有效,并且在使用匿名身份验证时有效:

<sec:authorize access="isAuthenticated()">
    <sec:authentication property="principal.username" var="username" />
</sec:authorize>
<sec:authorize access="!isAuthenticated()">
    <sec:authentication property="principal" var="username" />
</sec:authorize>

Later...之后...

Hello ${username}

I agree with alephx , I even voted his answer.我同意alephx ,我什至投票给他的答案。

But if you need another approach, you could use the one that Spring Roo uses.但是,如果您需要另一种方法,则可以使用 Spring Roo 使用的方法。

If you have the SecurityContextHolderAwareRequestFilter, it provides the standard servlet API security methods, using a request wrapper which accesses the SecurityContext.如果您有 SecurityContextHolderAwareRequestFilter,它提供标准的 servlet API 安全方法,使用访问 SecurityContext 的请求包装器。

This filter is registered with the <http> tag from the Spring Security namespace.此过滤器使用 Spring Security 命名空间中的<http>标记注册。 You can also register it in the FilterChainProxy's security filter chain (just add the reference to a declared bean in your applicationContext-security.xml)您还可以在 FilterChainProxy 的安全过滤器链中注册它(只需在 applicationContext-security.xml 中添加对声明的 bean 的引用)

Then, you can access the security servlet API as Roo does (find the footer.jspx to see how a conditional logout link is written)然后,您可以像 Roo 一样访问安全 servlet API(找到 footer.jspx 以查看条件注销链接是如何编写的)

  <c:if test="${pageContext['request'].userPrincipal != null}">
<c:out value=" | "/>
...

j tag is: j标签是:

<%@taglib prefix="j" uri="http://java.sun.com/jsp/jstl/core" %>

sec tag is:秒标签是:

<%@taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>

Add to pom.xml:添加到 pom.xml:

<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-taglibs</artifactId>
    <version>3.1.3.RELEASE</version>
</dependency>

Add to the page:添加到页面:

<sec:authentication var="principal" property="principal"/>
<j:choose>
    <j:when test="${principal eq 'anonymousUser'}">
          NOT AUTHENTICATED
    </j:when>
    <j:otherwise>
          AUTHENTICATED
    </j:otherwise>
</j:choose>

For accessing a principal attribute use, first, create a variable for attributes:要访问主体属性使用,首先,为属性创建一个变量:

<sec:authentication property="principal.attributes" var="principalAttr"/>

Then, you can use this map for retrieving values by the attribute key name:然后,您可以使用此映射按属性键名称检索值:

${principalAttr.get("given_name")}

Do not forget to add spring security taglib in your maven dependencies list:不要忘记在您的 Maven 依赖项列表中添加 spring security taglib:

    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-taglibs</artifactId>
        <version>5.3.4.RELEASE</version>
    </dependency>

据我所知默认的Spring Security 3.0.x中安装一个SecurityContextHolderRquestAwareFilter ,这样就可以得到Authentication通过调用对象HttpServletRequest.getUserPrincipal()你也可以查询通过调用角色HttpServletRequest.isUserInRole()

1) MY CUSTOM USER CLASS with extra field mobile: 1)我的自定义用户类,带有额外的现场移动:

 public class SiteUser extends User {

    public SiteUser(String username, String password, Collection<? extends GrantedAuthority> authorities,
            String mobile) {
        super(username, password, true, true, true, true, authorities);
        this.mobile = mobile;
    }

    private String mobile;

    public String getMobile() {
        return mobile;
    }

    public void setMobile(String mobile) {
        this.mobile = mobile;
    }

}

2) IN MY UserDetailsServiceImpl.java I POPULATED THIS CUSTOM SiteUser object. 2) 在我的 UserDetailsS​​erviceImpl.java 中,我填充了这个自定义 SiteUser 对象。

public SiteUser loadUserByUsername(String username)  {
        UserInfoVO userInfoVO = userDAO.getUserInfo(username);
        GrantedAuthority authority = new SimpleGrantedAuthority(userInfoVO.getRole());

        SiteUser siteUser = new SiteUser(userInfoVO.getUsername(), userInfoVO.getPassword(),
                Arrays.asList(authority), userInfoVO.getMobile());

        return siteUser;
}

3) AND IN VIEW I AM ACCESSING IT AS: 3)并且我认为我正在访问它:

< a href="#" th:text="${#httpServletRequest.userPrincipal.principal.mobile}"> <a href="#" th:text="${#httpServletRequest.userPrincipal.principal.mobile}">

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM