1 Spring Security介紹
Spring Security 的前身是 Acegi Security ,是 Spring 項目組中用來提供安全認證服務的框架。
(https://projects.spring.io/spring-security/) Spring Security 爲基於J2EE企業應用軟件提供了全面安全服務。特別是使用領先的J2EE解決方案-Spring框架開發的企業軟件項目。人們使用Spring Security有很多種原因,不過通常吸引他們的是在J2EE Servlet規範或EJB規範中找不到典型企業應用場景的解決方案。 特別要指出的是他們不能再WAR 或 EAR 級別進行移植。這樣,如果你更換服務器環境,就要,在新的目標環境進行大量的工作,對你的應用系統進行重新配 置安全。使用Spring Security 解決了這些問題,也爲你提供很多有用的,完全可以指定的其他安全特性。
安全包括兩個主要操作。
- “認證”,是爲用戶建立一個他所聲明的主體。主題一般式指用戶,設備或可以在你係 統中執行動作的其他系
統。 - “授權”指的是一個用戶能否在你的應用中執行某個操作,在到達授權判斷之前,身份的主題已經由 身份驗證過程建立了。
這些概念是通用的,不是Spring Security特有的。在身份驗證層面,Spring Security廣泛支持各種身份驗證模式,這些驗證模型絕大多數都由第三方提供,或則正在開發的有關標準機構提供的,例如 Internet Engineering TaskForce.作爲補充,Spring Security 也提供了自己的一套驗證功能。
Spring Security 目前支持認證一體化如下認證技術: HTTP BASIC authentication headers (一個基於IEFT RFC 的標準) HTTP Digest authentication headers (一個基於IEFT RFC 的標準) HTTP X.509 client certificate exchange(一個基於IEFT RFC 的標準) LDAP (一個非常常見的跨平臺認證需要做法,特別是在大環境) Form-basedauthentication (提供簡單用戶接口的需求) OpenID authentication Computer Associates Siteminder JA-SIGCentral Authentication Service (CAS,這是一個流行的開源單點登錄系統) Transparent authentication context propagation for Remote Method Invocation and HttpInvoker (一個Spring遠程調用協議)
2 入門案例
2.1 導入依賴
- pom.xml
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<spring.version>5.0.2.RELEASE</spring.version>
<spring.security.version>5.0.1.RELEASE</spring.security.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>${spring.security.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>${spring.security.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
2.2 在 web.xml 中創建 filter
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>Archetype Created Web Application</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-security.xml</param-value>
</context-param>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
</web-app>
2.3 spring security配置 文件
- spring-security.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:security="http://www.springframework.org/schema/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd">
<!-- 配置不過濾的資源(靜態資源及登錄相關) -->
<security:http security="none" pattern="/login.html" />
<security:http security="none" pattern="/failer.html" />
<security:http auto-config="true" use-expressions="false" >
<!-- 配置資料連接,表示任意路徑都需要ROLE_USER權限 -->
<security:intercept-url pattern="/**" access="ROLE_USER" />
<!-- 自定義登陸頁面,login-page 自定義登陸頁面 authentication-failure-url 用戶權限校驗失敗之後纔會跳轉到這個頁面,如果數據庫中沒有這個用戶則不會跳轉到這個頁面。
default-target-url 登陸成功後跳轉的頁面。 注:登陸頁面用戶名固定 username,密碼 password,action:login -->
<security:form-login login-page="/login.html"
login-processing-url="/login" username-parameter="username"
password-parameter="password" authentication-failure-url="/failer.html"
default-target-url="/success.html"
/>
<!-- 登出, invalidate-session 是否刪除session logout-url:登出處理鏈接 logout-success-url:登出成功頁面
注:登出操作 只需要鏈接到 logout即可登出當前用戶 -->
<security:logout invalidate-session="true" logout-url="/logout"
logout-success-url="/login.jsp" />
<!-- 關閉CSRF,默認是開啓的 -->
<security:csrf disabled="true" />
</security:http>
<security:authentication-manager>
<security:authentication-provider>
<security:user-service>
<security:user name="user" password="{noop}user"
authorities="ROLE_USER" />
<security:user name="admin" password="{noop}admin"
authorities="ROLE_ADMIN" />
</security:user-service>
</security:authentication-provider>
</security:authentication-manager>
</beans>
3 使用自定義頁面
- spring-security.xml
<!-- 自定義登陸頁面,login-page 自定義登陸頁面 authentication-failure-url 用戶權限校驗失敗之後纔會跳轉到這個頁面,如果數據庫中沒有這個用戶則不會跳轉到這個頁面。
default-target-url 登陸成功後跳轉的頁面。 注:登陸頁面用戶名固定 username,密碼 password,action:login -->
<security:form-login login-page="/login.html"
login-processing-url="/login" username-parameter="username"
password-parameter="password" authentication-failure-url="/failer.html"
default-target-url="/success.html" authentication-success-forward-url="/success.html"
/>
login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登錄頁面</title>
</head>
<body>
<form action="login" method="post">
<table>
<tr>
<td>用戶名:</td>
<td><input type="text" name="username" /></td>
</tr>
<tr>
<td>密碼:</td>
<td><input type="password" name="password" /></td>
</tr>
<tr>
<td colspan="2" align="center"><input type="submit" value="登錄" />
<input type="reset" value="重置" /></td>
</tr>
</table>
</form>
</body>
</html>
3 Spring Security使用數據庫認證
在Spring Security中如果想要使用數據進行認證操作,有很多種操作方式,這裏我們介紹使用UserDetails、UserDetailsService來完成操作。
3.1UserDetails
UserDetails是一個接口,可以認爲UserDetails作用是於封裝當前進行認證的用戶信息,但由於其是一個接口,所以我們可以對其進行實現,也可以使用Spring Security提供的一個UserDetails的實現類User來完成操作