今天我們將探討基於角色的Spring安全存取和授權示例。但在閱讀本文之前,請先閱讀我的上一篇文章,了解有關“Spring 4安全MVC登錄登出示例”的基本知識。
Spring安全角色
在這篇文章中,我們將討論如何在Spring Web應用程序中定義、使用和管理Spring安全角色,如“USER”、“ADMIN”。像我的上一篇文章一樣,本文示例也使用Spring 4 MVC安全性與內存存儲和Spring Java配置功能來開發應用程序。這意味著我們不會使用web.xml文件,也不會編寫一行Spring XML配置。我們將使用“In-Memory Store”選項來存儲和管理用戶憑據。我們將使用Spring 4.0.2.RELEASE、Spring STS 3.7套件IDE、Spring TC Server 3.1與Java 1.8和Maven構建工具來開發此示例。
基於Spring安全角色的存取授權示例
- 在Spring STS Suite中創建一個“Simple Spring Web Maven”項目,詳細如下。
項目名稱:SpringMVCSecruityMavenRolesApp2。使用前文中的pom.xml文件,但進行以下更改
<artifactId>SpringMVCSecruityMavenRolesApp</artifactId>
<build>
<finalName>SpringMVCSecruityMavenRolesApp</finalName>
</build>
</project>
- 使用前文中的所有Java和JSP文件。我們只討論這裡更新或新添加的內容。
- 更新LoginSecurityConfig.java文件以配置用戶角色,如“USER”和“ADMIN”。
LoginSecurityConfig.java
package com.journaldev.spring.secuity.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@Configuration
@EnableWebSecurity
public class LoginSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
public void configureGlobal(AuthenticationManagerBuilder authenticationMgr) throws Exception {
authenticationMgr.inMemoryAuthentication()
.withUser("jduser").password("jdu@123").authorities("ROLE_USER")
.and()
.withUser("jdadmin").password("jda@123").authorities("ROLE_USER","ROLE_ADMIN");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/homePage").access("hasRole('ROLE_USER') or hasRole('ROLE_ADMIN')")
.antMatchers("/userPage").access("hasRole('ROLE_USER')")
.antMatchers("/adminPage").access("hasRole('ROLE_ADMIN')")
.and()
.formLogin().loginPage("/loginPage")
.defaultSuccessUrl("/homePage")
.failureUrl("/loginPage?error")
.usernameParameter("username").passwordParameter("password")
.and()
.logout().logoutSuccessUrl("/loginPage?logout");
}
}
代碼解釋
- 在configureGlobal()方法中,我們添加了兩個用戶:一個用戶具有“ROLE_USER”角色,另一個用戶具有“ROLE_USER”和“ROLE_ADMIN”角色。這意味著第二個用戶將充當管理員用戶。我們可以配置任意數量的用戶和角色。
- 我們可以使用authorities(ROLE)或roles(ROLE)方法來配置應用程序中的角色。
- authorities()和roles()方法之間的區別:
- authorities()需要完整的角色名稱,如“ROLE_USER”
- roles()需要角色名稱,如“USER”。它將自動將“ROLE_”值添加到此“USER”角色名稱。
- 在configure()方法中,我們定義了不同URL與所需的訪問角色。
antMatchers("/homePage")
.access("hasRole('ROLE_USER') or hasRole('ROLE_ADMIN')")
此代碼片段配置了“/homePage”可供USER和ADMIN角色使用。
.antMatchers("/userPage").access("hasRole('ROLE_USER')")
.antMatchers("/adminPage").access("hasRole('ROLE_ADMIN')")
此代碼片段配置了“/userPage”僅由“USER”角色訪問,“/adminPage”僅由“ADMIN”角色訪問。如果其他角色訪問這些頁面,將獲得“403 Access is Denied”錯誤消息。
- LoginController.java
package com.journaldev.spring.web.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
@Controller
public class LoginController {
@RequestMapping(value = { "/"}, method = RequestMethod.GET)
public ModelAndView welcomePage() {
ModelAndView model = new ModelAndView();
model.setViewName("welcomePage");
return model;
}
@RequestMapping(value = { "/homePage"}, method = RequestMethod.GET)
public ModelAndView homePage() {
ModelAndView model = new ModelAndView();
model.setViewName("homePage");
return model;
}
@RequestMapping(value = {"/userPage"}, method = RequestMethod.GET)
public ModelAndView userPage() {
ModelAndView model = new ModelAndView();
model.setViewName("userPage");
return model;
}
@RequestMapping(value = {"/adminPage"}, method = RequestMethod.GET)
public ModelAndView adminPage() {
ModelAndView model = new ModelAndView();
model.setViewName("adminPage");
return model;
}
@RequestMapping(value = "/loginPage", method = RequestMethod.GET)
public ModelAndView loginPage(@RequestParam(value = "error",required = false) String error,
@RequestParam(value = "logout", required = false) String logout) {
ModelAndView model = new ModelAndView();
if (error != null) {
model.addObject("error", "Invalid Credentials provided.");
}
if (logout != null) {
model.addObject("message", "Logged out from JournalDEV successfully.");
}
model.setViewName("loginPage");
return model;
}
}
代碼解釋 除了之前的示例外,我們還添加了兩個新的URL。
-
“/userPage”由“USER”角色使用,用於訪問和執行普通用戶活動。
-
“/adminPage”由“ADMIN”角色使用,用於訪問和執行管理員用戶活動。 ADMIN角色也可以訪問“/userPage” URL。
-
更新homePage.jsp文件以提供用戶和管理員角色特定的活動。
homePage.jsp
<%@taglib prefix="c" uri="https://java.sun.com/jsp/jstl/core"%>
<a href="${pageContext.request.contextPath}/userPage">JD User</a> | <a href="${pageContext.request.contextPath}/adminPage">JD Admin</a> | <a href="javascript:document.getElementById('logout').submit()">Logout</a>
<h3>Welcome to JournalDEV Tutorials</h3>
<ul>
<li>Java 8 tutorial</li>
<li>Spring tutorial</li>
<li>Gradle tutorial</li>
<li>BigData tutorial</li>
</ul>
<c:url value="/logout" var="logoutUrl" />
<form id="logout" action="${logoutUrl}" method="post" >
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
</form>
這裡我們在頂部框架上添加了三個類似菜單的選項。 “Logout”已在我之前的帖子中討論過。新的兩個鏈接是:
- JD用戶:由“USER”和“ADMIN”角色都可以訪問
- JD管理員:僅由“ADMIN”角色訪問
注意:-在實時應用程序中,我們將僅向“USER”角色顯示“JD用戶”鏈接,並隱藏“JD管理員”鏈接。為了測試它是否可由“USER”角色訪問,以及查看確切的錯誤消息,我們沒有隱藏此鏈接。20. 添加新的adminPage.jsp文件,作為“ADMIN”角色的主頁。
adminPage.jsp
<%@taglib prefix="c" uri="https://java.sun.com/jsp/jstl/core"%>
<h3>Welcome to JournalDEV Tutorials</h3>
<h3>Admin Page</h3>
<c:url value="/logout" var="logoutUrl" />
<form id="logout" action="${logoutUrl}" method="post" >
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
</form>
<c:if test="${pageContext.request.userPrincipal.name != null}">
<a href="javascript:document.getElementById('logout').submit()">Logout</a>
</c:if>
- 新增userPage.jsp檔案以作為“USER”角色的首頁。
userPage.jsp
<%@taglib prefix="c" uri="https://java.sun.com/jsp/jstl/core"%>
<h3>Welcome to JournalDEV Tutorials</h3>
<h3>User Page</h3>
<c:url value="/logout" var="logoutUrl" />
<form id="logout" action="${logoutUrl}" method="post" >
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
</form>
<c:if test="${pageContext.request.userPrincipal.name != null}">
<a href="javascript:document.getElementById('logout').submit()">Logout</a>
</c:if>
我們現在已完成應用程式開發。是時候查看我們的專案最終結構並測試應用程式了。26. 最終專案結構如下:
Spring安全性角色示例應用程式測試
- 右鍵單擊Spring STS IDE中的項目,並選擇“運行 AS >> 在服務器上運行”選項。
將訪問默認的應用程序歡迎頁面,如下所示:3。點擊“登錄到JournalDEV”鏈接。現在您已經在登錄頁面。
5。首先使用“USER”角色憑據登錄:
用戶名:jduser 密碼:jdu@123現在我們將看到應用程序主頁,其中包含3個菜單選項:“JD User”、“JD Admin”和“Logout”。點擊“JD User”鏈接。由於我們使用“USER”角色憑據登錄應用程序,因此可以像下面顯示的那樣訪問此鏈接。
只需在Spring STS IDE中使用向後箭頭,然後這次點擊“JD Admin”鏈接。
由於我們使用“USER”角色憑據登錄,所以無法訪問此鏈接。這就是我們看到此錯誤消息的原因:“403訪問被拒絕”。9。現在已登錄並再次使用ADMIN角色憑據登錄
用戶名:jdadmin 密碼:jda@123這次我們可以成功訪問“JD Admin”鏈接,如下所示。測試“Logout”鏈接以退出應用程序。
那就是關於 Spring 安全性角色的範例,以提供對 Web 應用程式頁面的授權訪問。