Spring Security教程(四)


在前面三個博客的例子中,登陸頁面都是用的Spring Security自己提供的,這明顯不符合實際開發場景,同時也沒有退出和注銷按鈕,因此在每次測試的時候都要通過關閉瀏覽器來注銷達到清除session的效果。

 

一 自定義頁面

login.jsp:
<%@ page language="java" contentType="text/html; charset=utf-8"
	pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>自定義登陸頁面</title>
</head>
<body>
	<div class="error ${param.error == true ? '' : 'hide'}">
		登陸失敗<br>
		${sessionScope['SPRING_SECURITY_LAST_EXCEPTION'].message}
	</div>
	<form method="post" action="${pageContext.request.contextPath}/j_spring_security_check" style="width:260px; text-align: center">
		<fieldset>
			<legend>登陸</legend>
			用戶: <input type="text" name="j_username" style="width: 150px;"
				value="${sessionScope['SPRING_SECURITY_LAST_USERNAME']}" /><br />
			密碼: <input type="password" name="j_password" style="width: 150px;" /><br />
			<input type="checkbox" name="_spring_security_remember_me" />兩周之內不必登陸<br />
			<input type="submit" value="登陸" /> <input type="reset" value="重置" />
		</fieldset>
	</form>
 
</body>
</html>

  

說明:
1、特別要注意的是form表單的action是提交登陸信息的地址,這是security內部定義好的,同時自定義form時,要把form的action設置為/j_spring_security_check。注意這里要使用絕對路徑,避免登陸頁面存放的頁面可能帶來的問題。
2、j_username,輸入登陸名的參數名稱,j_password,輸入密碼的參數名稱,這兩個正常情況下也不會修改。

3、_spring_security_remember_me,選擇是否允許自動登錄的參數名稱。可以直接把這個參數設置為一個checkbox,無需設置value,Spring Security會自行判斷它是否被選中,這也是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-3.0.xsd
    					http://www.springframework.org/schema/context
    					http://www.springframework.org/schema/context/spring-context-3.1.xsd
                		http://www.springframework.org/schema/tx
                		http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
                		http://www.springframework.org/schema/security
                		http://www.springframework.org/schema/security/spring-security.xsd">
	
	<!-- <http pattern="/login.jsp" security="none"></http> -->
	<http auto-config="false">
	    <intercept-url pattern="/login.jsp" access="IS_AUTHENTICATED_ANONYMOUSLY" />
	    <intercept-url pattern="/adminPage.jsp" access="ROLE_ADMIN" />
	    <intercept-url pattern="/**" access="ROLE_USER" />
	    <form-login login-page="/login.jsp" default-target-url="/index.jsp"
	        authentication-failure-url="/login.jsp?error=true" />
	    <logout invalidate-session="true"
		      logout-success-url="/login.jsp"
		      logout-url="/j_spring_security_logout"/>  
	</http>
	<!-- 數據源 -->
	<beans:bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
		destroy-method="close">
		<!-- 此為c3p0在spring中直接配置datasource c3p0是一個開源的JDBC連接池 -->
		<beans:property name="driverClass" value="com.mysql.jdbc.Driver" />
 
		<beans:property name="jdbcUrl"
			value="jdbc:mysql://localhost:3306/springsecuritydemo?useUnicode=true&characterEncoding=UTF-8" />
		<beans:property name="user" value="root" />
		<beans:property name="password" value="" />
		<beans:property name="maxPoolSize" value="50"></beans:property>
		<beans:property name="minPoolSize" value="10"></beans:property>
		<beans:property name="initialPoolSize" value="10"></beans:property>
		<beans:property name="maxIdleTime" value="25000"></beans:property>
		<beans:property name="acquireIncrement" value="1"></beans:property>
		<beans:property name="acquireRetryAttempts" value="30"></beans:property>
		<beans:property name="acquireRetryDelay" value="1000"></beans:property>
		<beans:property name="testConnectionOnCheckin" value="true"></beans:property>
		<beans:property name="idleConnectionTestPeriod" value="18000"></beans:property>
		<beans:property name="checkoutTimeout" value="5000"></beans:property>
		<beans:property name="automaticTestTable" value="t_c3p0"></beans:property>
	</beans:bean>
	
	<authentication-manager>
	   	<authentication-provider>
	   	    <jdbc-user-service data-source-ref="dataSource"
	   	        users-by-username-query="select username,password,status as enabled from user where username = ?"
	   	        authorities-by-username-query="select user.username,role.name from user,role,user_role 
	   	        					where user.id=user_role.user_id and 
	   	        					user_role.role_id=role.id and user.username=?"/>
	   	</authentication-provider>
	</authentication-manager>
</beans:beans>

  

說明:
1、form-login這個標簽是配置登陸頁面的,其中的屬性login-page是配置登陸頁面的,default-target-url配置登陸成功后跳轉到的頁面,authentication-failure-url配置認證失敗后的跳轉頁面。
2、在上面的配置中,登陸頁面肯定是不能攔截的,任何人都應該可以訪問,<intercept-url pattern="/login.jsp" access="IS_AUTHENTICATED_ANONYMOUSLY" />配置表示允許匿名用戶訪問,就是不用身份都可以訪問;還有另一種配置方式:<http pattern="/login.jsp" security="none"></http>,這種配置達到的目的都是一樣的。
3、logout這個標簽用來配置退出或者注銷,其中的屬性invalidate-session,配置否是要清除session,logout-success-url配置注銷成功后的跳轉頁面,logout-url提交退出或者注銷的地址,因此我們在配置退出或者注銷的時候,只需要將url設置為/j_spring_security_logout即可,這個地址也是security內部實現了的。
4、form-login標簽中還有一個特別要注意的屬性use-expressions,如果設置為true,這配置access就要做相應的改變,否則項目啟動的時候會報錯,錯誤如下:

如果use-expressns="true"時,則表示改為 SpEL 表達式。 SpEL 允許使用特定的訪問控制規則表達式語言。與簡單的字符串如 ROLE_USER 不同,配置文件可以指明表達式語言觸發方法調用、引用系統屬性、計算機值等等。http標簽中的配置改為如下:

<http auto-config="false" use-expressions="true">
	    <intercept-url pattern="/login.jsp" access="permitAll" />
	    <intercept-url pattern="/adminPage.jsp" access="hasRole('ROLE_ADMIN')" />
	    <intercept-url pattern="/**" access="hasRole('ROLE_USER')" />
	    <form-login login-page="/login.jsp" default-target-url="/index.jsp"
	        authentication-failure-url="/login.jsp?error=true" />
	    <logout invalidate-session="true"
		      logout-success-url="/login.jsp"
		      logout-url="/j_spring_security_logout"/>  
	</http>

  配置文件中的其他配置在前面幾篇博客中都有詳細的講解,這里就不贅述了。

三 其他文件

index.jsp

 
<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
	<h1>this is a user page</h1>
	<a href="${pageContext.request.contextPath}/j_spring_security_logout">退出登陸</a>
</body>
</html>

  adminPage.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
	<h1>this is a admin page</h1>
	<a href="${pageContext.request.contextPath}/j_spring_security_logout">退出登陸</a>
</body>
</html>

  

這里定義了兩個頁面,index.jsp用戶和管理員都可以訪問,adminPage.jsp只有管理員可以訪問,同時兩個頁面都有注銷按鈕,注銷按鈕提交的地址也就是上面配置文件中的地址/j_spring_security_logout。
pom.xml和前面的一樣,這里就不貼了。

 

四 結果

當輸入普通用戶的用戶名和密碼,同時勾選2周不用登陸后,因為adminPage.jsp頁面要有管理員權限才能訪問,所以普通用戶訪問失敗,index.jsp頁面就可以訪問;這時關閉頁面后,再次訪問資源,因為勾選了2周不用登陸,所以可以成功訪問;但是當點擊退出登錄后,再次訪問是就會跳轉到登陸頁面,要求登陸才能訪問。

當輸入管理員名和密碼,同時勾選2周不用登陸,驗證成功后,跳轉到index.jsp,同時adminPage.jsp也可以訪問,這時把一個頁面關閉再重新訪問資源時,因為勾選2周不用登陸,所以可以成功訪問;然后注銷,這是再訪問資源時,就會跳轉到登陸頁面,要求登陸才能訪問。



---------------------
作者:AirMario
來源:CSDN
原文:https://blog.csdn.net/AirMario/article/details/54022812


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM