1. 程式人生 > >Spring Security的基本使用

Spring Security的基本使用

1、在web.xml中配置spring security的過濾器代理: filter-class = org.springframework.web.filter.DelegatingFilterProxy,

  這個代理會把過濾到請求自動轉到 springSecurityFilterChain 這個類裡面,這個是spring security的一個處理類
  這個過濾器要配置 <filter-name>springSecurityFilterChain</filter-name>  這裡的name固定要是springSecurityFilterChain,因為他是security內建好的過濾器名稱

2、在spring配置檔案中加入spring security的配置(這裡加入一個配置檔案,用來配置security相關–spring-security.xml)

  a).在spring-security.xml中配置spring security的頁面攔截規則:
<!-- security的頁面攔截規則, use-expressions表示是否啟用SPEL表示式,預設是true -->
<http use-expressions="false">
	<!-- 攔截的路徑: /* 表示只攔截根目錄下的資源,不包括它子目錄的資源; /** 就是包括所有的資源 -->
	<!-- access 配置security的角色名,security規定角色名必須是ROLE_開頭的(如果上面不配置use-expressions=false,這裡就要寫成 hasRole(ROLE_USER')) -->
	<intercept-url pattern="/**" access="ROLE_USER"/>
	<!-- 開啟表單登入功能 -->
	<form-login/>
</http>

b).在spring-security.xml中配置認證管理器
<!-- 認證管理器 -->
<authentication-manager>
	<!-- 認證的提供者 -->
	<authentication-provider>
		<user-service>
			<!-- user用來配置當前系統的使用者,name就是使用者的name,authorities是角色名 -->
			<!-- 這個配置的意思是:配置一個使用者admin,密碼是123456,角色是ROLE_USER,如果admin登入之後,就能訪問ROLE_USER這個角色配置的資源,如果不是這個使用者登入,或者沒有登入,就不能訪問 -->
			<user name="admin" password="123456" authorities="ROLE_USER"/>			
		</user-service>
	</authentication-provider>
</authentication-manager>

3、啟動專案,訪問專案(如果沒有自己寫登入頁面),因為在spring-security.xml配置了 (開啟表單登入功能),所以spring security會幫我們自動生成一個登陸頁面。

   如果不登入,直接訪問index.html,會跳轉到這個登陸頁面,如果不使用 admin 123456登陸,也會提示登陸失敗,只有使用admin 123456登陸後,才能跳轉到index.html頁面

4、使用自己定義的登入頁面,配置詳細看spring-security.xml檔案

 <!-- 以下頁面不登入也能訪問 -->
<http pattern="/login.html" security="none"/>
<http pattern="/login_error.html" security="none"/>

5、在攔截規則中,加入,表示關閉攔截csrf攔截機制

 CSRF(Cross-site request forgery)跨站請求偽造,也被稱為“One Click Attack”或者Session Riding,通常縮寫為CSRF或者XSRF,是一種對網站的惡意利用,如果是jsp頁面,那每個頁面都會自帶csrf
 在html頁面中,也可以在js程式碼中,給請求新增csrf頭資訊,適用於傳送ajax請求

6、上述的做法在登入的時候沒有查詢資料庫,而是在spring security配置檔案中寫死的username,password,下面是從資料庫查詢使用者進行spring security的登入:

 a). pom.xml,web.xml,login.html中的form表單裡面的寫法都同上面一樣
 b). 寫一個UserDetailsServiceImpl 繼承 UserDetailsService,這是security認證介面的實現類,UserDetailsService是security自己定義的一個認證類,
  這裡要實現裡面一個方法,loadUserByUsername(String username),當用戶在頁面登入後,通過security的配置,請求會自動進入到這個方法裡面

 c). public UserDetails loadUserByUsername(String username)
		throws UsernameNotFoundException {
	
	System.out.println("經過了UserDetailsServiceImpl...");
	
	//grantAuths是表示這個使用者在security認證之後的角色的集合
	List<GrantedAuthority> grantAuths = new ArrayList<GrantedAuthority>();
	//這個list裡面要放GrantedAuthority物件,但是它是一個介面,所以放它的實現類  SimpleGrantedAuthority
	grantAuths.add(new SimpleGrantedAuthority("ROLE_SELLER"));		//security規定角色名必須是ROLE_ 開頭

	//這個User類也是security定義的一個類,它是 UserDetails 的實現類
	//這個返回的User的意思是,當用戶登入輸入的使用者名稱=username,密碼=123456時,就登入成功,反之不成功(username和123456應該是從資料庫查出來的)
	User user = new User(username, "123456", grantAuths);
	
	return user;
 }
 
d). 當用呼叫服務層的應用訪問資料庫時,需要一個sellerService物件:
    /**呼叫服務層訪問資料庫,來查詢使用者*/
	private SellerService sellerService;
	
	/**因為當前類所在的包不在controller裡面,所以不能dubbo的@Reference來注入物件,這裡採用spring配置檔案的形式注入物件,所以這裡要提供一個set方法*/
	public void setSellerService(SellerService sellerService) {
		this.sellerService = sellerService;
	}
	
e). <!-- 自定義的認證介面的實現類 -->
	<bean:bean id="userDetailService" class="com.pinyougou.service.UserDetailsServiceImpl">
		<!-- 這裡使用spring配置檔案的bean注入sellerService物件,這裡的name和和UserDetailsServiceImpl裡面的屬性名一樣 -->
		<bean:property name="sellerService" ref="sellerService"/>
	</bean:bean>
	
	<!-- 採用dubbo,從遠端引入一個sellerService的物件,id就是物件的名字 -->
	<dubbo:application name="pinyougou-shop-web" />
	<dubbo:registry address="zookeeper://192.168.25.128:2181"/>
	<dubbo:reference interface="com.pinyougou.sellergoods.service.SellerService" id="sellerService"/>