spring-cecurity的簡介:html
Spring Security是一個可以爲基於Spring的企業應用系統提供聲明式的安全訪問控制解決方案的安全框架。它提供了一組能夠在Spring應用上下文中配置的Bean,充分利用了Spring IoC,DI(控制反轉Inversion of Control ,DI:Dependency Injection 依賴注入)和AOP(面向切面編程)功能,爲應用系統提供聲明式的安全訪問控制功能,減小了爲企業系統安全控制編寫大量重複代碼的工做。java
本博客包含的功能:web
1)使用基本的spring-security demo的實現,採用spring-security默認的登陸算法
2)在spring-security的基礎上自定義登陸頁面以及註銷功能spring
3)使用spring-security數據庫中獲取數據進行登陸驗證數據庫
4)使用spring-decurity的BCrypt對密碼進行加密處理express
1.新建一個war包類型的maven項目apache
注:新建的maven工程須要轉換爲Web工程的方法和項目的pom.xml中報錯:web.xml is missing and <failOnMissingWebXml> is set to true 解決方法請看:編程
https://www.cnblogs.com/sun-flower1314/p/11732915.html瀏覽器
2.在pom.xml中加入Spring Security的maven配置
<properties> <spring.version>4.2.4.RELEASE</spring.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.security</groupId> <artifactId>spring-security-web</artifactId> <version>4.1.0.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-config</artifactId> <version>4.1.0.RELEASE</version> </dependency> </dependencies> <build> <plugins> <!-- java編譯插件 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.2</version> <configuration> <source>1.7</source> <target>1.7</target> <encoding>UTF-8</encoding> </configuration> </plugin> <plugin> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat7-maven-plugin</artifactId> <configuration> <!-- 指定端口 --> <port>9080</port> <!-- 請求路徑 --> <path>/</path> </configuration> </plugin> </plugins> </build>
3.在/src/main/resources下新建spring-security.xml的配置文件。
該配置文件與以往的稍有不一樣,須要注意的點有:
以往的前綴<beans ></beans>是直接這樣,是默認爲beans
如今的爲<beans:beans > </beans:beans>,默認的xmlns爲security的,由於這裏使用的基本都是以<security:xxx >開頭,爲了省去麻煩,因此將security配置爲默認的。
<?xml version="1.0" encoding="UTF-8"?> <beans:beans xmlns="http://www.springframework.org/schema/security" xmlns:beans="http://www.springframework.org/schema/beans" 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"> <http use-expressions="false"> <intercept-url pattern="/**" access="ROLE_USER" /> <form-login /> </http> <!-- 認證管理器 --> <authentication-manager> <authentication-provider> <user-service> <user name="admin" password="123456" authorities="ROLE_USER" /> </user-service> </authentication-provider> </authentication-manager> </beans:beans>
spring-security.xml配置文件中屬性說明:
<1> <http >標籤中:屬性use-expressions 表示是否啓動SPEL表達式 false表示不啓用,若不配置use-expressions屬性,則在子標籤intercept-url中需配置access=hasRole('ROLE_USER')
<2><intercept-url>表示攔截url,其屬性pattern="/*" 表示只攔截根目錄下的資源,不包括子目錄中的資源, /** 攔截全部資源; 屬性access表示配置角色名稱 其值必須是【ROLE_】開頭
<3><form-login /> 表示開啓表單功能
<4><authentication-provider> 表示認證提供者
<5><user >標籤配置當前系統的登陸用戶:用戶名 name; 密碼 password; 當前用戶所屬角色 authorities
4.配置web.xml文件,整個文件爲:
其中包含加載了classpath:spring-security.xml文件以及加入了一個安全過濾器,其中的springSecurityFilterChain爲固定名稱,不能改變
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5"> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring-security.xml</param-value> </context-param> <listener> <listener-class> org.springframework.web.context.ContextLoaderListener </listener-class> </listener> <!-- 安全過濾器 --> <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> </web-app>
5. 而後啓動用maven命令啓動項目,tomcat7:run ,啓動成功後,在瀏覽器中輸入地址訪問,即便沒有寫任何界面,也可看到security默認的登陸界面:
6.輸入用戶名和密碼,若輸入錯誤的用戶名和密碼,可看到以下界面:
輸入正確用戶密碼登陸後,會顯示404錯誤,由於沒有配置默認的首頁,在webapp下配置index.html頁面便可。
7.用戶自定義登陸頁
實際開發中,不可能使用系統的默認登陸頁
1)構建登陸頁
①form表單中規定 action=「/login" method="post"
②<input >輸入用戶規定的 name="username";輸入密碼框規定name="password"
即以下所示:
<form action='/login' method='POST'> <table> <tr> <td>用戶名:</td> <td><input type='text' name='username' value=''></td> </tr> <tr> <td>密碼:</td> <td><input type='password' name='password' /></td> </tr> <tr> <td colspan='2'><input name="submit" type="submit" value="登錄" /></td> </tr> </table> </form>
2)構建登錄失敗頁 login_error.html(內容略)
3)再次修改spring-security.xml的配置文件
增長配置說明以下:
<1>login-page:指定登陸頁面。
<2>authentication-failure-url:指定了身份驗證失敗時跳轉到的頁面。
<3>default-target-url:指定了成功進行身份驗證和受權後默認呈現給用戶的頁面。
<4>csrf disabled="true" 關閉csrf
<5><headers><frame-options policy="SAMEORIGIN"/> </headers> 表示在頁面中還存在iframe標籤嵌入其餘頁面
<6><logout/> 表示註銷退出,而且在註銷按鈕中配置的action爲:/logout
<!-- 如下頁面不被攔截 -->
<http pattern="/login.html" security="none"></http>
<http pattern="/login_error.html" security="none"></http>
<!-- 頁面攔截規則 -->
<http use-expressions="false">
<intercept-url pattern="/*" access="ROLE_USER" />
<form-login login-page="/login.html" default-target-url="/index.html" authentication-failure-url="/login_error.html" always-use-default-target="true" />
<csrf disabled="true"/>
<!-- <headers>
<frame-options policy="SAMEORIGIN"/>
</headers> -->
<logout/>
</http>
其中security="none"表示次資源不被攔截,若未設置登陸頁,則會出現如下錯誤
csrf disabled="true" 關閉csrf ,若是不加會出現錯誤,CSRF(Cross-site request forgery)跨站請求僞造,也被稱爲「One Click Attack」或者Session Riding,一般縮寫爲CSRF或者XSRF,是一種對網站的惡意利用。
八、從數據庫中匹配用戶名和密碼,而不用配置文件中的用戶名和密碼
1)編寫驗證明現類,即繼承Security自帶的接口UserDetailsService
LoginCheck.java
package com.hxc.securityDemo; import java.util.ArrayList; import java.util.List; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; public class LoginCheck implements UserDetailsService { @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { //1.構建角色列表 List<GrantedAuthority> grantedAuthorities = new ArrayList<GrantedAuthority>(); grantedAuthorities.add(new SimpleGrantedAuthority("ROLE_ADMIN")); String password = "123456"; //2.從數據庫中查詢數據進行檢驗 // TbUser tbUser = userService.findOne(username); // if(tbUser == null) { // return null; // } // password = tbUser.getPassword(); //... //new User 爲Security包中的類,其中第一個參數爲登陸界面輸入的用戶名,第二個爲後臺參數的密碼(即從數據庫中查詢),第三個爲權限角色 return new User(username, password, grantedAuthorities); } }
2)在spring-security.xml配置文件中 將認證管理 修改成以下:
<authentication-manager>
<authentication-provider user-service-ref="userDetailService">
</authentication-provider>
</authentication-manager>
<beans:bean id="userDetailService" class="com.hxc.securityDemo.LoginCheck"></beans:bean>
9.自定義密碼加密處理
對於存入數據庫中密碼,不能顯示成明文,而須要通過加密處理。而傳統的MD5加密算法,雖然時不可逆算法加密,但能夠在網上的彩虹表破解獲得,由於其對同一密碼MD5加密後生成的都是同一密碼,固定不變。若採用BCrypt加密,即便時同一密碼,其加密後獲得的密碼也是不一樣的。其原理是會先使用一個特定的字符串(如域名)加密,再使用一個隨機的salt(鹽值)加密。特定字符串是程序代碼中固定的,salt是每一個密碼單獨隨機,混入最終加密後的密碼,驗證時也無需單獨提供以前的salt,從而無需單獨處理salt問題。
對於在項目中添加用戶時密碼處理以下:
public boolean add(TbUser user) { String userPassword = user.getPassword(); BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); String encPassword = passwordEncoder.encode(userPassword); // System.out.println(encPassword); //存入數據庫中.... //..... // return true; }
用戶登陸驗證時,在spring-security.xml中的認證管理配置以下:
<beans:bean id="userDetailService" class="com.hxc.securityDemo.LoginCheck" /> <beans:bean id="bcryptEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder" /> <authentication-manager alias="authenticationManager"> <authentication-provider user-service-ref='userDetailService'> <password-encoder ref="bcryptEncoder"></password-encoder> </authentication-provider> </authentication-manager>
自此 自定義配置完成