© 版权声明:本文为博主原创文章,转载请注明出处
1.项目结构
2.pom.xml
1 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 2 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 3 4 <modelVersion>4.0.0</modelVersion> 5 6 <groupId>org.springsecurity</groupId> 7 <artifactId>SpringSecurity</artifactId> 8 <packaging>war</packaging> 9 <version>0.0.1-SNAPSHOT</version> 10 <name>SpringSecurity Maven Webapp</name> 11 <url>http://maven.apache.org</url> 12 13 <!-- 统一版本 --> 14 <properties> 15 <jdk.version>1.7</jdk.version> 16 <spring.version>4.3.5.RELEASE</spring.version> 17 <spring.security.version>4.2.1.RELEASE</spring.security.version> 18 </properties> 19 20 <dependencies> 21 <!-- junit依赖 --> 22 <dependency> 23 <groupId>junit</groupId> 24 <artifactId>junit</artifactId> 25 <version>4.12</version> 26 <scope>test</scope> 27 </dependency> 28 <!-- spring依赖 --> 29 <dependency> 30 <groupId>org.springframework</groupId> 31 <artifactId>spring-core</artifactId> 32 <version>${spring.version}</version> 33 </dependency> 34 <dependency> 35 <groupId>org.springframework</groupId> 36 <artifactId>spring-web</artifactId> 37 <version>${spring.version}</version> 38 </dependency> 39 <dependency> 40 <groupId>org.springframework</groupId> 41 <artifactId>spring-webmvc</artifactId> 42 <version>${spring.version}</version> 43 </dependency> 44 <!-- spring security依赖 --> 45 <dependency> 46 <groupId>org.springframework.security</groupId> 47 <artifactId>spring-security-web</artifactId> 48 <version>${spring.security.version}</version> 49 </dependency> 50 <dependency> 51 <groupId>org.springframework.security</groupId> 52 <artifactId>spring-security-config</artifactId> 53 <version>${spring.security.version}</version> 54 </dependency> 55 <!-- SpringSecurity标签库依赖 --> 56 <dependency> 57 <groupId>org.springframework.security</groupId> 58 <artifactId>spring-security-taglibs</artifactId> 59 <version>${spring.security.version}</version> 60 </dependency> 61 <!-- jsp、servlet依赖 --> 62 <dependency> 63 <groupId>jstl</groupId> 64 <artifactId>jstl</artifactId> 65 <version>1.2</version> 66 </dependency> 67 <dependency> 68 <groupId>taglibs</groupId> 69 <artifactId>standard</artifactId> 70 <version>1.1.2</version> 71 </dependency> 72 <dependency> 73 <groupId>javax.servlet</groupId> 74 <artifactId>javax.servlet-api</artifactId> 75 <version>3.1.0</version> 76 </dependency> 77 </dependencies> 78 <build> 79 <finalName>SpringSecurity</finalName> 80 </build> 81 </project>
3.mvc-dispatcher-servlet.xml
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:context="http://www.springframework.org/schema/context" 5 xsi:schemaLocation="http://www.springframework.org/schema/beans 6 http://www.springframework.org/schema/beans/spring-beans.xsd 7 http://www.springframework.org/schema/context 8 http://www.springframework.org/schema/context/spring-context.xsd"> 9 10 <!-- 开启包扫描 --> 11 <context:component-scan base-package="org.springsecurity.*"/> 12 13 <!-- 定义视图解析器 --> 14 <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> 15 <property name="prefix"> 16 <value>/WEB-INF/pages/</value> 17 </property> 18 <property name="suffix"> 19 <value>.jsp</value> 20 </property> 21 </bean> 22 23 </beans>
4.spring-security.xml
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:security="http://www.springframework.org/schema/security" 5 xsi:schemaLocation="http://www.springframework.org/schema/beans 6 http://www.springframework.org/schema/beans/spring-beans.xsd 7 http://www.springframework.org/schema/security 8 http://www.springframework.org/schema/security/spring-security.xsd"> 9 10 <security:http auto-config="true"> 11 <!-- 指定需要拦截的URL,并设置访问所需的角色 --> 12 <security:intercept-url pattern="/" 13 access="hasRole('USER') or hasRole('ADMIN') or hasRole('DBA')"/> 14 <!-- 测试中发现SpringSecurity会自动在角色名称前加上ROLE_。即ROLE_USER == USER --> 15 <security:intercept-url pattern="/home**" 16 access="hasRole('USER') or hasRole('ADMIN')or hasRole('DBA')"/> 17 <!-- login-page:跳转到登录界面的请求名称 18 default-target-url:指定身份验证通过后默认执行的请求名称 19 authentication-failure-url:如果验证失败,则转向URL 20 username-parameter:表示登录时用户使用的是哪个参数,即用户名输入框的name 21 password-parameter:表示登录时密码使用的是哪个参数,即密码输入框的name 22 --> 23 <security:form-login login-page="/login" default-target-url="/home" 24 authentication-failure-url="/login?error" username-parameter="username" 25 password-parameter="password"/> 26 <!-- 开启csrf,在登录或注销页面都必须包含_csrf.token --> 27 <security:csrf/> 28 </security:http> 29 30 <security:authentication-manager> 31 <security:authentication-provider> 32 <security:user-service> 33 <!-- 设置用户的密码和角色,authorities指定角色必须加上ROLE_,否则会报错403:Access is denied --> 34 <security:user name="admin" password="123456" authorities="ROLE_ADMIN" /> 35 <security:user name="user" password="123456" authorities="ROLE_USER" /> 36 <security:user name="dba" password="123456" authorities="ROLE_DBA" /> 37 </security:user-service> 38 </security:authentication-provider> 39 </security:authentication-manager> 40 41 </beans>
5.web.xml
1 <web-app xmlns="http://java.sun.com/xml/ns/javaee" 2 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 3 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 4 http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" 5 version="3.0" metadata-complete="true"> 6 7 <!-- Spring MVC --> 8 <servlet> 9 <servlet-name>mvc-dispatcher</servlet-name> 10 <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 11 <init-param> 12 <param-name>contextConfigLocation</param-name> 13 <param-value>classpath:mvc-dispatcher-servlet.xml</param-value> 14 </init-param> 15 </servlet> 16 <servlet-mapping> 17 <servlet-name>mvc-dispatcher</servlet-name> 18 <url-pattern>/</url-pattern> 19 </servlet-mapping> 20 21 <listener> 22 <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 23 </listener> 24 25 <!-- 加载spring-security配置文件 --> 26 <context-param> 27 <param-name>contextConfigLocation</param-name> 28 <param-value>classpath:spring-security.xml</param-value> 29 </context-param> 30 31 <!-- spring security --> 32 <filter> 33 <filter-name>springSecurityFilterChain</filter-name> 34 <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> 35 </filter> 36 <filter-mapping> 37 <filter-name>springSecurityFilterChain</filter-name> 38 <url-pattern>/*</url-pattern> 39 </filter-mapping> 40 41 </web-app>
6.HelloController.java
1 package org.springsecurity.controller; 2 3 import org.springframework.security.core.context.SecurityContextHolder; 4 import org.springframework.security.core.userdetails.UserDetails; 5 import org.springframework.stereotype.Controller; 6 import org.springframework.web.bind.annotation.RequestMapping; 7 import org.springframework.web.bind.annotation.RequestMethod; 8 import org.springframework.web.bind.annotation.RequestParam; 9 import org.springframework.web.servlet.ModelAndView; 10 11 @Controller 12 public class HelloController { 13 14 @RequestMapping(value = {"/", "/home**"}, method = RequestMethod.GET) 15 public ModelAndView welcomePage() { 16 17 ModelAndView model = new ModelAndView(); 18 model.addObject("user", getPrincipal()); 19 model.setViewName("success"); 20 return model; 21 22 } 23 24 @RequestMapping(value = "/login", method = RequestMethod.GET) 25 public ModelAndView login( 26 @RequestParam(value = "error", required = false) String error, 27 @RequestParam(value = "logout", required = false) String logout) { 28 29 ModelAndView model = new ModelAndView(); 30 if(error != null){ 31 model.addObject("error", "违法的用户名或密码!"); 32 } 33 if(logout != null){ 34 model.addObject("msg", "您已成功注销!"); 35 } 36 model.setViewName("login"); 37 return model; 38 39 } 40 41 private String getPrincipal() { 42 43 String username = null; 44 Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal(); 45 if(principal instanceof UserDetails) { 46 username = ((UserDetails) principal).getUsername(); 47 } else { 48 username = principal.toString(); 49 } 50 return username; 51 52 } 53 54 }
7.login.jsp
1 <%@ page language="java" contentType="text/html; charset=UTF-8" 2 pageEncoding="UTF-8"%> 3 <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 4 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 5 <html> 6 <head> 7 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 8 <title>Insert title here</title> 9 </head> 10 <body onload="focus()"> 11 <h1>Spring Security 自定义登录界面</h1> 12 <div id="login-box"> 13 <c:if test="${not empty error }"> 14 <div class="error"><font color="red">${error }</font><br/><br/></div> 15 </c:if> 16 <c:if test="${not empty msg }"> 17 <div class="msg"><font color="red">${msg }</font><br/><br/></div> 18 </c:if> 19 <!-- SpringSecurity3.x默认的登录拦截URL是/j_spring_security_check; 20 4.x默认的登录拦截URL是/login --> 21 <form name="loginForm" action="<c:url value='/login'/>" method="POST"> 22 <table> 23 <tr> 24 <td>用户名:</td> 25 <!-- name必须与spring-security.xml中配置的username-parameter一致,否则登录认证会失败 --> 26 <td><input type="text" name="username"/></td> 27 </tr> 28 <tr> 29 <td>密码:</td> 30 <!-- name必须与spring-security.xml中配置的password-parameter一致,否则登录认证会失败 --> 31 <td><input type="password" name="password"></td> 32 </tr> 33 <tr style="text-align: center;" > 34 <td colspan="2"> 35 <input type="reset" value="重置"/> 36 <input type="submit" value="登录"/> 37 </td> 38 </tr> 39 </table> 40 <!-- 开启csrf后必须包含_csrf.token,否则报错: 41 403 Could not verify the provided CSRF token because your session was not found --> 42 <input type="hidden" name="${_csrf.parameterName }" value="${_csrf.token }"/> 43 </form> 44 </div> 45 </body> 46 <script type="text/javascript"> 47 48 function focus(){//设置加载时鼠标焦点 49 50 document.loginForm.username.focus(); 51 52 } 53 54 </script> 55 </html>
8.success.jsp
1 <%@ page language="java" contentType="text/html; charset=UTF-8" 2 pageEncoding="UTF-8"%> 3 <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 4 <%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %> 5 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 6 <html> 7 <head> 8 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 9 <title>Insert title here</title> 10 </head> 11 <body> 12 Dear <strong>${user }</strong>, Welcome to Home Page. 13 <a href="javascript:formSubmit()">Logout</a> 14 15 <!-- 隐藏域,用于提交注销请求 --> 16 <c:url value="/logout" var="logoutUrl"/> 17 <!-- 假设注销请求是*,若*=logout(即等于默认的注销拦截URL),则实际请求是/login?logout 18 若*!=logout,则实际请求是/*。具体原因未知。。 --> 19 <form action="${logoutUrl }" method="POST" id="logoutForm"> 20 <!-- 开启csrf后必须包含_csrf.token,否则报错: 21 403 Could not verify the provided CSRF token because your session was not found --> 22 <input type="hidden" name="${_csrf.parameterName }" value="${_csrf.token }"> 23 </form> 24 25 <br/><br/> 26 This part is visible to Everyone. 27 <sec:authorize access="hasRole('USER')"><!-- USER角色专有 --> 28 This part is visible to <font color="red">USER</font>. 29 </sec:authorize> 30 <sec:authorize access="hasRole('ADMIN')"><!-- ADMIN角色专有 --> 31 This part is visible to <font color="red">ADMIN</font>. 32 </sec:authorize> 33 <sec:authorize access="hasRole('DBA')"><!-- DBA角色专有 --> 34 This part is visible to <font color="red">DBA</font>. 35 </sec:authorize> 36 </body> 37 <script type="text/javascript"> 38 39 function formSubmit(){//提交注销请求表单 40 41 document.getElementById("logoutForm").submit(); 42 43 } 44 45 </script> 46 </html>
9.效果预览
9.1 登录界面
9.2 ADMIN角色登录
9.3 DBA角色登录
9.4 USER角色登录
参考:http://www.yiibai.com/spring-security/spring-security-4-secure-view-layer-using-taglibs.html