[英]Get Spring Security Principal in JSP EL expression
我正在使用 Spring MVC 和 Spring Security 版本 3.0.6.RELEASE。 在我的 JSP 中獲取用戶名的最簡單方法是什么? 或者甚至只是用戶是否登錄? 我可以想到幾種方法:
使用這樣的腳本來確定用戶是否已登錄:
<%=org.springframework.security.core.context.SecurityContextHolder.getContext()
.getAuthentication().getPrincipal().equals("anonymousUser")
? "false":"true"%>
不過,我不喜歡使用 scriptlet,我想在一些<c:if>
標簽中使用它,這需要將它作為頁面屬性放回去。
我可以再次使用@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) 在我的 UserDetailsServiceImpl.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.