Spring Security 自定义登录页面
SpringMVC + Spring Security,自定义登录页面登录验证
学习参考:http://www.mkyong.com/spring-security/spring-security-form-login-example/
使用的过滤器:
1、web.authentication.logout.LogoutFilter:
监控一个实际为退出功能的URL(默认为/j_spring_security_logout),并且在匹配退出功能。
2、web.authentication.UsernamePasswordAuthenticationFilter:
监控一个使用用户名和密码基于form认证的/j_spring_security_check),并在URL匹配该用户。
项目结构如下图
1、Maven的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/xsd/maven-4.0.0.xsd"> 3 <modelVersion>4.0.0</modelVersion> 4 <groupId>com.mcs</groupId> 5 <artifactId>springmvc01</artifactId> 6 <version>0.0.1-SNAPSHOT</version> 7 <packaging>war</packaging> 8 9 <properties> 10 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 11 </properties> 12 13 <dependencies> 14 <!-- junit --> 15 <dependency> 16 <groupId>junit</groupId> 17 <artifactId>junit</artifactId> 18 <scope>test</scope> 19 </dependency> 20 <!-- log4j --> 21 <dependency> 22 <groupId>log4j</groupId> 23 <artifactId>log4j</artifactId> 24 </dependency> 25 <!-- servlet --> 26 <dependency> 27 <groupId>javax.servlet</groupId> 28 <artifactId>javax.servlet-api</artifactId> 29 <scope>provided</scope> 30 </dependency> 31 <dependency> 32 <groupId>javax.servlet.jsp</groupId> 33 <artifactId>javax.servlet.jsp-api</artifactId> 34 <scope>provided</scope> 35 </dependency> 36 <dependency> 37 <groupId>javax.servlet</groupId> 38 <artifactId>jstl</artifactId> 39 </dependency> 40 41 <!-- spring --> 42 <dependency> 43 <groupId>org.springframework</groupId> 44 <artifactId>spring-core</artifactId> 45 </dependency> 46 <dependency> 47 <groupId>org.springframework</groupId> 48 <artifactId>spring-context</artifactId> 49 </dependency> 50 <dependency> 51 <groupId>org.springframework</groupId> 52 <artifactId>spring-context-support</artifactId> 53 </dependency> 54 <dependency> 55 <groupId>org.springframework</groupId> 56 <artifactId>spring-orm</artifactId> 57 </dependency> 58 <dependency> 59 <groupId>org.springframework</groupId> 60 <artifactId>spring-webmvc</artifactId> 61 </dependency> 62 <dependency> 63 <groupId>org.springframework</groupId> 64 <artifactId>spring-tx</artifactId> 65 </dependency> 66 <dependency> 67 <groupId>org.springframework</groupId> 68 <artifactId>spring-jdbc</artifactId> 69 </dependency> 70 <dependency> 71 <groupId>org.springframework</groupId> 72 <artifactId>spring-aspects</artifactId> 73 </dependency> 74 <dependency> 75 <groupId>org.springframework</groupId> 76 <artifactId>spring-messaging</artifactId> 77 </dependency> 78 <dependency> 79 <groupId>org.springframework</groupId> 80 <artifactId>spring-test</artifactId> 81 </dependency> 82 <!-- spring security --> 83 <dependency> 84 <groupId>org.springframework.security</groupId> 85 <artifactId>spring-security-core</artifactId> 86 </dependency> 87 <dependency> 88 <groupId>org.springframework.security</groupId> 89 <artifactId>spring-security-web</artifactId> 90 </dependency> 91 <dependency> 92 <groupId>org.springframework.security</groupId> 93 <artifactId>spring-security-config</artifactId> 94 </dependency> 95 <dependency> 96 <groupId>org.springframework.security</groupId> 97 <artifactId>spring-security-taglibs</artifactId> 98 </dependency> 99 <dependency> 100 <groupId>org.springframework.security</groupId> 101 <artifactId>spring-security-acl</artifactId> 102 </dependency> 103 <dependency> 104 <groupId>org.springframework.security</groupId> 105 <artifactId>spring-security-data</artifactId> 106 </dependency> 107 <!-- spring data jpa --> 108 <dependency> 109 <groupId>org.springframework.data</groupId> 110 <artifactId>spring-data-jpa</artifactId> 111 </dependency> 112 <dependency> 113 <groupId>org.springframework.data</groupId> 114 <artifactId>spring-data-rest-webmvc</artifactId> 115 </dependency> 116 117 <!-- jackson --> 118 <dependency> 119 <groupId>com.fasterxml.jackson.core</groupId> 120 <artifactId>jackson-core</artifactId> 121 </dependency> 122 <dependency> 123 <groupId>com.fasterxml.jackson.core</groupId> 124 <artifactId>jackson-databind</artifactId> 125 </dependency> 126 <dependency> 127 <groupId>com.fasterxml.jackson.core</groupId> 128 <artifactId>jackson-annotations</artifactId> 129 </dependency> 130 131 <!-- commons --> 132 <dependency> 133 <groupId>commons-logging</groupId> 134 <artifactId>commons-logging</artifactId> 135 </dependency> 136 <dependency> 137 <groupId>commons-io</groupId> 138 <artifactId>commons-io</artifactId> 139 </dependency> 140 <dependency> 141 <groupId>commons-fileupload</groupId> 142 <artifactId>commons-fileupload</artifactId> 143 </dependency> 144 145 <!-- mysql --> 146 <dependency> 147 <groupId>mysql</groupId> 148 <artifactId>mysql-connector-java</artifactId> 149 </dependency> 150 <!-- c3p0 --> 151 <dependency> 152 <groupId>com.mchange</groupId> 153 <artifactId>c3p0</artifactId> 154 </dependency> 155 156 </dependencies> 157 158 <dependencyManagement> 159 <dependencies> 160 <dependency> 161 <groupId>io.spring.platform</groupId> 162 <artifactId>platform-bom</artifactId> 163 <version>2.0.0.RELEASE</version> 164 <type>pom</type> 165 <scope>import</scope> 166 </dependency> 167 <dependency> 168 <groupId>org.springframework</groupId> 169 <artifactId>spring-framework-bom</artifactId> 170 <version>4.2.3.RELEASE</version> 171 <type>pom</type> 172 <scope>import</scope> 173 </dependency> 174 <dependency> 175 <groupId>org.springframework.data</groupId> 176 <artifactId>spring-data-releasetrain</artifactId> 177 <version>Gosling-SR1</version> 178 <type>pom</type> 179 <scope>import</scope> 180 </dependency> 181 </dependencies> 182 </dependencyManagement> 183 184 <repositories> 185 <!-- ... possibly other repository elements ... --> 186 <repository> 187 <id>spring-milestone</id> 188 <name>Spring Milestone Repository</name> 189 <url>http://repo.springsource.org/milestone</url> 190 </repository> 191 </repositories> 192 193 </project>
2、spring-mvc.xml
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 3 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd 4 http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd"> 5 6 <context:component-scan base-package="com.mcs.action.**" /> 7 8 <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> 9 <property name="prefix" value="/WEB-INF/views/"></property> 10 <property name="suffix" value=".jsp"></property> 11 </bean> 12 13 </beans>
3、spring-security.xml
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:security="http://www.springframework.org/schema/security" xsi:schemaLocation="http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-4.0.xsd 3 http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> 4 5 <!-- auto-config = true 则使用from-login. 如果不使用该属性 则默认为http-basic(没有session). --> 6 <security:http auto-config="true"> 7 <!-- intercept-url:拦截器,可以设定哪些路径需要哪些权限来访问. filters=none 不使用过滤,也可以理解为忽略 --> 8 <security:intercept-url pattern="/admin**" access="hasRole('ROLE_USER')" /> 9 10 <!-- 11 login-page:默认指定的登录页面. 12 authentication-failure-url:出错后跳转页面. 13 default-target-url:成功登陆后跳转页面 默认登录保护url 14 --> 15 <security:form-login 16 login-page="/login.action" 17 default-target-url="/welcome.action" 18 authentication-failure-url="/login.action?error" 19 login-processing-url="/j_spring_security_check" 20 username-parameter="username" 21 password-parameter="password" /> 22 23 <!-- logout-success-url:成功注销后跳转到的页面; --> 24 <security:logout 25 logout-url="/j_spring_security_logout" 26 logout-success-url="/login.action" 27 invalidate-session="true" /> 28 29 <security:http-basic /> 30 31 <!-- enable csrf protection --> 32 <security:csrf /> 33 </security:http> 34 35 <security:authentication-manager> 36 <security:authentication-provider> 37 <security:user-service> 38 <security:user name="admin" password="1234" authorities="ROLE_USER" /> 39 </security:user-service> 40 </security:authentication-provider> 41 </security:authentication-manager> 42 43 </beans>
4、web.xml
1 <?xml version="1.0" encoding="UTF-8"?> 2 <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 3 xmlns="http://xmlns.jcp.org/xml/ns/javaee" 4 xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" 5 id="WebApp_ID" version="3.1"> 6 7 <!-- 项目名称 --> 8 <display-name>Spring security</display-name> 9 10 <!-- 配置字符集过滤器 --> 11 <!-- 必须配置在所有过滤器的前面 --> 12 <filter> 13 <filter-name>encodingFilter</filter-name> 14 <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> 15 <init-param> 16 <param-name>encoding</param-name> 17 <param-value>UTF-8</param-value> 18 </init-param> 19 </filter> 20 <!-- 配置项目的编码mapping --> 21 <filter-mapping> 22 <filter-name>encodingFilter</filter-name> 23 <url-pattern>/*</url-pattern> 24 </filter-mapping> 25 26 <!-- 配置spring security filter --> 27 <filter> 28 <filter-name>springSecurityFilterChain</filter-name> 29 <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> 30 </filter> 31 <filter-mapping> 32 <filter-name>springSecurityFilterChain</filter-name> 33 <url-pattern>/*</url-pattern> 34 </filter-mapping> 35 36 <!-- 开启spring功能 --> 37 <listener> 38 <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 39 </listener> 40 41 <!-- 防止内存溢出监听器 --> 42 <listener> 43 <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class> 44 </listener> 45 46 <!-- 指定spring相关文件的位置 --> 47 <context-param> 48 <param-name>contextConfigLocation</param-name> 49 <param-value>classpath:spring-security.xml</param-value> 50 </context-param> 51 52 <!-- 配置spring mvc --> 53 <servlet> 54 <servlet-name>springMvc</servlet-name> 55 <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 56 <init-param> 57 <param-name>contextConfigLocation</param-name> 58 <param-value>classpath:spring-mvc.xml</param-value> 59 </init-param> 60 <load-on-startup>1</load-on-startup> 61 </servlet> 62 <!-- 配置spring mvc mapping --> 63 <servlet-mapping> 64 <servlet-name>springMvc</servlet-name> 65 <url-pattern>*.action</url-pattern> 66 </servlet-mapping> 67 68 69 70 <!-- 配置session超时时间,单位分钟 --> 71 <session-config> 72 <session-timeout>15</session-timeout> 73 </session-config> 74 75 <!-- 设置欢迎页面 --> 76 <welcome-file-list> 77 <welcome-file>/index.jsp</welcome-file> 78 </welcome-file-list> 79 80 81 </web-app>
5、HelloController
1 package com.mcs.action; 2 3 import org.springframework.stereotype.Controller; 4 import org.springframework.web.bind.annotation.RequestMapping; 5 import org.springframework.web.bind.annotation.RequestMethod; 6 import org.springframework.web.bind.annotation.RequestParam; 7 import org.springframework.web.servlet.ModelAndView; 8 9 @Controller 10 public class HelloController { 11 12 @RequestMapping(value = { "/", "/welcome**" }, method = RequestMethod.GET) 13 public ModelAndView welcomePage() { 14 15 ModelAndView model = new ModelAndView(); 16 model.addObject("title", "Spring Security Hello World"); 17 model.addObject("message", "这是一个欢迎页面!"); 18 model.setViewName("hello"); 19 return model; 20 21 } 22 23 @RequestMapping(value = "/admin**", method = RequestMethod.GET) 24 public ModelAndView adminPage() { 25 26 ModelAndView model = new ModelAndView(); 27 model.addObject("title", "Spring Security Hello World"); 28 model.addObject("message", "这是一个安全被保护的页面!"); 29 model.setViewName("admin"); 30 31 return model; 32 33 } 34 35 //Spring Security see this : 36 @RequestMapping(value = "/login", method = RequestMethod.GET) 37 public ModelAndView login( 38 @RequestParam(value = "error", required = false) String error, 39 @RequestParam(value = "logout", required = false) String logout) { 40 41 ModelAndView model = new ModelAndView(); 42 if (error != null) { 43 model.addObject("error", "用户名或密码不正确!"); 44 } 45 46 if (logout != null) { 47 model.addObject("msg", "您已成功注销系统."); 48 } 49 model.setViewName("login"); 50 51 return model; 52 53 } 54 55 56 }
6、hello.jsp
1 <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> 2 <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> 3 <%@page session="false"%> 4 <html> 5 <body> 6 <h1>标题 : ${title}</h1> 7 <h1>消息 : ${message}</h1> 8 </body> 9 </html>
7、login.jsp
1 <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> 2 <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> 3 <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%> 4 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 <style> 11 .error { 12 padding: 15px; 13 margin-bottom: 20px; 14 border: 1px solid transparent; 15 border-radius: 4px; 16 color: #a94442; 17 background-color: #f2dede; 18 border-color: #ebccd1; 19 } 20 21 .msg { 22 padding: 15px; 23 margin-bottom: 20px; 24 border: 1px solid transparent; 25 border-radius: 4px; 26 color: #31708f; 27 background-color: #d9edf7; 28 border-color: #bce8f1; 29 } 30 31 #login-box { 32 width: 300px; 33 padding: 20px; 34 margin: 100px auto; 35 background: #fff; 36 -webkit-border-radius: 2px; 37 -moz-border-radius: 2px; 38 border: 1px solid #000; 39 } 40 </style> 41 </head> 42 <body onload='document.loginForm.username.focus();'> 43 <div id="login-box"> 44 <h2>请输入您的用户名与密码</h2> 45 <c:if test="${not empty error}"> 46 <div class="error">${error}</div> 47 </c:if> 48 <c:if test="${not empty msg}"> 49 <div class="msg">${msg}</div> 50 </c:if> 51 52 <form name='loginForm' action="<c:url value='/j_spring_security_check' />" method='POST'> 53 <table> 54 <tr> 55 <td>用户:</td> 56 <td><input type='text' name='username' value=''></td> 57 </tr> 58 <tr> 59 <td>密码:</td> 60 <td><input type='password' name='password' /></td> 61 </tr> 62 <tr> 63 <td colspan='2'><input name="submit" type="submit" 64 value="登录" /></td> 65 </tr> 66 </table> 67 68 <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" /> 69 </form> 70 </div> 71 72 </body> 73 </html>
8、admin.jsp
1 <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> 2 <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> 3 <%@page session="true"%> 4 <html> 5 <body> 6 <h1>标题 : ${title}</h1> 7 <h1>消息 : ${message}</h1> 8 9 <c:url value="/j_spring_security_logout" var="logoutUrl" /> 10 11 <!-- csrt for log out--> 12 <form action="${logoutUrl}" method="post" id="logoutForm"> 13 <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" /> 14 </form> 15 16 <script> 17 function formSubmit() { 18 document.getElementById("logoutForm").submit(); 19 } 20 </script> 21 22 <c:if test="${pageContext.request.userPrincipal.name != null}"> 23 <h2> 24 欢迎 : ${pageContext.request.userPrincipal.name} 登录本系统 | <a 25 href="javascript:formSubmit()"> 注销</a> 26 </h2> 27 </c:if> 28 29 </body> 30 </html>