【问题标题】:Get Spring Security Principal in JSP EL expression在 JSP EL 表达式中获取 Spring Security Principal
【发布时间】:2012-02-21 08:51:22
【问题描述】:

我正在使用 Spring MVC 和 Spring Security 版本 3.0.6.RELEASE。在我的 JSP 中获取用户名的最简单方法是什么?甚至只是用户是否登录?我可以想到几种方法:

1。使用小脚本

使用这样的脚本来确定用户是否登录:

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

不过,我不喜欢使用 scriptlet,我想在一些 &lt;c:if&gt; 标记中使用它,这需要将其作为页面属性放回。

2。使用 SecurityContextHolder

我可以再次使用 @Controller 中的 SecurityContextHolder 并将其放在模型上。不过,我在每个页面上都需要这个,所以我宁愿不必在每个控制器中添加这个逻辑。

我怀疑有一种更清洁的方法可以做到这一点......

【问题讨论】:

    标签: java spring jsp spring-mvc spring-security


    【解决方案1】:

    查看 Spring 安全标签:&lt;sec:authentication property="principal.username" /&gt;

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

    您可以检查是否已登录:

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

    而不是 c:if

    【讨论】:

    • 完美!对于可能看到此内容的其他任何人,我必须将 添加到 spring-security.xml 以使其正常工作。
    • 太好了,好多了!如果其他人有这个问题,我的 spring 安全标签将被忽略,直到我在 pom.xml 中添加了 spring-security-taglibs 依赖项。
    【解决方案2】:

    我知道线程中还有其他答案,但没有人回答如何检查用户是否已通过身份验证。所以我正在分享我的代码的样子。

    在你的项目中包含标签库:

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

    然后通过添加在当前范围内创建一个用户对象:

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

    然后您可以通过添加轻松显示用户名。请记住,“主体”对象通常是字符串类型,除非您已经实现了 spring 安全性以将其更改为项目中的另一个类:

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

    我希望这对希望检查用户角色的人有所帮助。

    如果您使用的是 Maven,请添加 Christian Vielma 在此线程中提到的依赖标记。

    谢谢!

    【讨论】:

      【解决方案3】:

      你可以这样使用: Spring 安全标签库 - 3.1.3.RELEASE

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

      然后:

      ${principal.username}
      

      【讨论】:

        【解决方案4】:

        我使用的是 Maven,所以我必须将 taglibs 库添加到 pom.xml 中

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

        然后在我的jsp中添加:

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

        还有:

        <sec:authentication property="principal" />
        

        principal.username 不断给我错误(可能是我创建UsernamePasswordAuthenticationToken 对象的方式,不确定)。

        【讨论】:

          【解决方案5】:

          我同意 alephx,我什至投票给了他的答案。

          但如果您需要其他方法,您可以使用 Spring Roo 使用的方法。

          如果您有 SecurityContextHolderAwareRequestFilter,它使用访问 SecurityContext 的请求包装器提供标准 servlet API 安全方法。

          这个过滤器是使用 Spring Security 命名空间中的 &lt;http&gt; 标签注册的。您也可以在FilterChainProxy的安全过滤器链中注册它(只需在您的applicationContext-security.xml中添加对已声明bean的引用)

          然后,您可以像 Roo 一样访问安全 servlet API(找到 footer.jspx 以查看条件注销链接是如何编写的)

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

          【讨论】:

            【解决方案6】:

            我认为&lt;sec:authentication property="principal.username" /&gt; 并不总是有效,因为Authentication.getPrincipal() 返回的类型是Object,即:它可能是UserDetail(上面的方法适用)、String 或其他任何东西。

            为了在 JSP 页面中显示用户名,我发现更可靠的是使用 ${pageContext.request.userPrincipal.name}

            这使用返回字符串的java.security.Principal.getName()

            【讨论】:

            • 这在使用匿名身份验证时似乎不起作用
            【解决方案7】:

            无论用户是否登录都有效,并且在使用匿名身份验证时有效:

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

            稍后...

            Hello ${username}
            

            【讨论】:

              【解决方案8】:

              j 标记为:

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

              秒标签是:

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

              添加到 pom.xml:

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

              添加到页面:

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

              【讨论】:

              • 谢谢!!新版spring boot的正确答案
              【解决方案9】:

              据我所知默认Spring Security 3.0.x installs一个SecurityContextHolderRquestAwareFilter,这样就可以调用HttpServletRequest.getUserPrincipal()获取Authentication对象,也可以调用HttpServletRequest.isUserInRole()查询角色。

              【讨论】:

              • 我试过了,至少使用表达式${request.userPrincipal},但它返回null。也许我做了一些事情来打破它......不过,谢谢!
              • @Jeremiah Orr 这很奇怪,我有几个应用程序依赖于 Spring Security 和 Servlet API 之间的集成。也许您已经指定了一个自定义 Spring Security 堆栈而不是使用默认堆栈?
              【解决方案10】:

              为了访问主要属性使用,首先,为属性创建一个变量:

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

              然后,您可以使用此映射通过属性键名称检索值:

              ${principalAttr.get("given_name")}
              

              不要忘记在你的maven依赖列表中添加spring security taglib:

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

              【讨论】:

                【解决方案11】:

                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) 在我的 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) 并且我正在访问它:

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 2011-03-22
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2020-11-04
                  • 2010-12-19
                  • 2011-09-09
                  • 1970-01-01
                  相关资源
                  最近更新 更多