简体   繁体   中英

Get Spring Security Principal in JSP EL expression

I am using Spring MVC and Spring Security version 3.0.6.RELEASE. What is the easiest way to get the user name in my JSP? Or even just whether or not the user is logged in? I can think of a couple ways:

1. Using a scriptlet

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.

2. Using SecurityContextHolder

I could again use SecurityContextHolder from my @Controller and put it on the model. 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" />

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

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:

<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.

Thanks!

You can use like this: 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

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

Then in my jsp added:

<%@ 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).

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.

For purpose of displaying username in JSP page what I find more reliable is using ${pageContext.request.userPrincipal.name} .

This uses java.security.Principal.getName() which returns String.

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.

But if you need another approach, you could use the one that Spring Roo uses.

If you have the SecurityContextHolderAwareRequestFilter, it provides the standard servlet API security methods, using a request wrapper which accesses the SecurityContext.

This filter is registered with the <http> tag from the Spring Security namespace. 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)

Then, you can access the security servlet API as Roo does (find the footer.jspx to see how a conditional logout link is written)

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

j tag is:

<%@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:

<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:

    <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:

 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.

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:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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