簡體   English   中英

在 JSP EL 表達式中獲取 Spring Security Principal

[英]Get Spring Security Principal in JSP EL expression

我正在使用 Spring MVC 和 Spring Security 版本 3.0.6.RELEASE。 在我的 JSP 中獲取用戶名的最簡單方法是什么? 或者甚至只是用戶是否登錄? 我可以想到幾種方法:

1. 使用腳本

使用這樣的腳本來確定用戶是否已登錄:

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

不過,我不喜歡使用 scriptlet,我想在一些<c:if>標簽中使用它,這需要將它作為頁面屬性放回去。

2. 使用 SecurityContextHolder

我可以再次使用@Controller SecurityContextHolder 並將其放在模型上。 不過,我在每一頁都需要這個,所以我寧願不必在我的每個控制器中添加這個邏輯。

我懷疑有一種更清潔的方法可以做到這一點......

檢查 Spring 安全標簽: <sec:authentication property="principal.username" />

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

您可以檢查是否已登錄:

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

而不是 c:if

我知道線程中還有其他答案,但沒有人回答如何檢查用戶是否已通過身份驗證。 所以我要分享我的代碼是什么樣子的。

在您的項目中包含標簽庫:

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

然后通過添加以下內容在當前范圍內創建一個用戶對象:

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

然后您可以通過添加輕松顯示用戶名。 請記住,'principal' 對象通常是字符串類型,除非您以某種方式實現了 spring 安全性,將其更改為項目中的另一個類:

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

我希望這對希望檢查用戶角色的人有所幫助。

如果您使用的是 Maven,請添加 Christian Vielma 在此線程中提到的依賴項標記。

謝謝!

你可以這樣使用:Spring Security Tag Lib - 3.1.3.RELEASE

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

接着:

${principal.username}

我正在使用 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對象的方式,不確定)。

我認為<sec:authentication property="principal.username" />並不總是有效,因為Authentication.getPrincipal()返回的類型是 Object,即:它可能是UserDetail (上面的方法適用)、String 或還要別的嗎。

為了在 JSP 頁面中顯示用戶名,我發現更可靠的是使用${pageContext.request.userPrincipal.name}

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

無論用戶是否登錄,這都有效,並且在使用匿名身份驗證時有效:

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

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

但是,如果您需要另一種方法,則可以使用 Spring Roo 使用的方法。

如果您有 SecurityContextHolderAwareRequestFilter,它提供標准的 servlet API 安全方法,使用訪問 SecurityContext 的請求包裝器。

此過濾器使用 Spring Security 命名空間中的<http>標記注冊。 您還可以在 FilterChainProxy 的安全過濾器鏈中注冊它(只需在 applicationContext-security.xml 中添加對聲明的 bean 的引用)

然后,您可以像 Roo 一樣訪問安全 servlet API(找到 footer.jspx 以查看條件注銷鏈接是如何編寫的)

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

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>

要訪問主體屬性使用,首先,為屬性創建一個變量:

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

據我所知默認的Spring Security 3.0.x中安裝一個SecurityContextHolderRquestAwareFilter ,這樣就可以得到Authentication通過調用對象HttpServletRequest.getUserPrincipal()你也可以查詢通過調用角色HttpServletRequest.isUserInRole()

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) 在我的 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)並且我認為我正在訪問它:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM