基于Spring Security角色的访问授权示例

时间:2020-02-23 14:36:01  来源:igfitidea点击:

今天,我们将研究基于Spring安全角色的访问和授权示例。
但是,在阅读本文之前,请仔细阅读我以前的文章" Spring 4 Security MVC登录注销示例",以获取有关Spring 4 Security的一些基本知识。

Spring安全角色

在本文中,我们将讨论如何在Spring Web Application中定义,使用和管理Spring安全角色,例如" USER"," ADMIN"。

就像我以前的文章一样,这个例子还使用Spring 4 MVC Security和内存中存储以及Spring Java配置功能来开发应用程序。
这意味着我们将不会使用web.xml文件,甚至不会编写Spring XML Configuration的一行。

我们将使用"内存中存储"选项来存储和管理用户凭据。

我们将使用Spring 4.0.2.RELEASE,Spring STS 3.7 Suite IDE,带有Java 1.8的Spring TC Server 3.1和Maven构建工具来开发此示例。

基于Spring Security角色的访问授权示例

  • 在Spring STS Suite中使用以下详细信息创建" Simple Spring Web Maven"项目。

项目名称:SpringMVCSecruityMavenRolesApp

  • 使用与我以前的帖子相同的pom.xml文件,并进行以下更改
<artifactId>SpringMVCSecruityMavenRolesApp</artifactId>

<build>
<finalName>SpringMVCSecruityMavenRolesApp</finalName>
</build>
</project>
  • 使用我以前的文章中的所有Java和JSP文件。
    我们将仅在此处讨论更新或者新增的内容。

  • 更新LoginSecurityConfig.java文件以配置用户角色,例如" USER"和" ADMIN"。

LoginSecurityConfig.java

package com.theitroad.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"角色的用户。
    这意味着该第二个用户将充当管理员用户。
    这样,我们可以配置任意数量的用户和角色。

  • 我们可以使用Authority(ROLE)或者Roles(ROLE)方法在应用程序中配置Roles。

  • Authoritys()和Roles()方法之间的区别:

  • Authority()需要完整的角色名称,例如" ROLE_USER"

  • role()需要角色名称,例如" 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访问被拒绝"错误消息。

  • 更新LoginController.java控制器文件以定义新的URL访问路径,如下所示。

LoginController.java

package com.theitroad.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 theitroad successfully.");
		}

		model.setViewName("loginPage");
		return model;
	}

}

代码说明除了前面的示例示例外,在这里我们还添加了两个新的URL。

  • 用户角色使用"/userPage"来访问和执行普通用户活动。

  • ADMIN角色使用"/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 theitroad 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>

其中我们在顶部添加了三个类似于菜单的选项。
在我之前的文章中已经讨论了"注销"。

新的两个链接是:

  • JD用户:" USER"和" ADMIN"角色均可访问
  • JD Admin:只能由两个" ADMIN"角色访问

注意:-在实时应用程序中,我们将仅显示" JD用户"链接到"用户"角色,并隐藏" JD管理员"链接。
为了测试"用户"角色是否可以访问它,并查看确切的错误消息,我们没有隐藏此链接。

  • 添加新的adminPage.jsp文件以充当" ADMIN"角色的主页。

adminPage.jsp

<%@taglib prefix="c" uri="https://java.sun.com/jsp/jstl/core"%>
<h3>Welcome to theitroad 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文件以充当"用户"角色的主页。

userPage.jsp

<%@taglib prefix="c" uri="https://java.sun.com/jsp/jstl/core"%>
<h3>Welcome to theitroad 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>

现在,我们已经完成了应用程序开发。
现在该查看我们项目的最终结构并测试应用程序。

  • 最终项目结构如下所示:

Spring安全角色示例应用程序测试

  • 在Spring STS IDE中右键单击Project,然后选择"运行AS >>在服务器上运行"选项。

它将访问默认的应用程序欢迎页面,如下所示:

  • 单击"登录到theitroad"链接。
    现在,您位于登录页面。

  • 首次使用" USER"角色凭证登录:

用户名:jduser密码:jdu @ 123

现在,我们将看到带有三个菜单选项的"应用程序主页":" JD用户"," JD管理员"和"注销"。

单击" JD用户"链接。
当我们使用"用户"角色凭证登录到应用程序后,我们可以如下所示访问此链接。

只需在Spring STS IDE中使用后退箭头,然后单击" JD Admin"链接。

由于我们已经使用" USER"角色凭证登录,因此无法访问此链接。
因此,我们看到以下错误消息:" 403访问被拒绝"。

  • 现在已登录,然后再次使用ADMIN角色凭据登录