【Spring Security】4、自定義頁面

在前面例子中,登錄頁面都是用的Spring Security本身提供的,這明顯不符合實際開發場景,同時也沒有退出和註銷按鈕,所以在每次測試的時候都要經過關閉瀏覽器來註銷達到清除session的效果。html

一 、自定義頁面

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>

說明:java

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

  • _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">
    <!-- 
    1.http部分配置如何攔截用戶請求。auto-config='true'將自動配置幾種經常使用的權限控制機制,包括form, anonymous, rememberMe。
    2.利用intercept-url來判斷用戶須要具備何種權限才能訪問對應的url資源,能夠在pattern中指定一個特定的url資源,也能夠使用通配符指定一組
    相似的url資源。例子中定義的兩個intercepter-url,第一個用來控制對/admin.jsp的訪問,第二個使用了通配符/**,說明它將控制對系統中全部
    url資源的訪問。
    3.在實際使用中,Spring Security採用的是一種就近原則,就是說當用戶訪問的url資源知足多個intercepter-url時,系統將使用第一個符合
    條件的intercept-url進行權限控制。在咱們這個例子中就是,當用戶訪問/admin.jsp時,雖然兩個intercept-url都知足要求,但由於第一個
    intercept-url排在上面,因此Spring Security會使用第一個intercept-url中的配置處理對/adminPage.jsp的請求,也就是說
    只有那些擁有了ROLE_ADMIN權限的用戶才能訪問/admin.jsp。
    4.access指定的權限都是以ROLE_開頭的,實際上這與Spring Security中的Voter機制有着千絲萬縷的聯繫,只有包含了特定前綴的字符串纔會
    被Spring Security處理。
     -->
    <http auto-config='true'>
        <!-- IS_AUTHENTICATED_ANONYMOUSLY表示容許匿名訪問 -->
        <intercept-url pattern="/page/login.jsp" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
        <!-- ROLE_ADMIN角色容許訪問 -->
        <intercept-url pattern="/page/admin.jsp" access="ROLE_ADMIN" />
        <!-- ROLE_USER角色容許訪問任何頁面,但不包括上面配置的頁面,由於SpringSecurity採用就近原則 -->
        <intercept-url pattern="/**" access="ROLE_USER" />
        <!-- 登陸頁面配置,default-target-url登陸成功頁面,authentication-failure-url失敗頁面 -->
        <form-login login-page="/page/login.jsp" default-target-url="/user.jsp" authentication-failure-url="/page/login.jsp?error=true"/>
        <!-- 註銷配置,invalidate-session是否清除緩存,logout-success-url註銷後跳轉頁面,logout-url提交地址 -->  
        <logout invalidate-session="true" logout-success-url="/page/login.jsp" logout-url="/j_spring_security_logout"/>    
    </http>
    
    <!-- 默認數據庫對用戶進行存儲 -->
    <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>

 

說明:
  • form-login這個標籤是配置登錄頁面的,其中的屬性login-page是配置登錄頁面的,default-target-url配置登錄成功後跳轉到的頁面,authentication-failure-url配置認證失敗後的跳轉頁面。
  • 在上面的配置中,登錄頁面確定是不能攔截的,任何人都應該能夠訪問,<intercept-url pattern="/page/login.jsp" access="IS_AUTHENTICATED_ANONYMOUSLY" />配置表示容許匿名用戶訪問,就是不用身份均可以訪問;還有另外一種配置方式:<http pattern="/page/login.jsp" security="none"></http>,這種配置達到的目的都是同樣的。
  • logout這個標籤用來配置退出或者註銷,其中的屬性invalidate-session,配置否是要清除session,logout-success-url配置註銷成功後的跳轉頁面,logout-url提交退出或者註銷的地址,所以咱們在配置退出或者註銷的時候,只須要將url設置爲/j_spring_security_logout便可,這個地址也是security內部實現了的。
  • form-login標籤中還有一個特別要注意的屬性use-expressions,若是設置爲true,對應登陸頁面intercept-url配置的access就要作相應的改變,不然項目啓動的時候會報錯,錯誤以下:
若是 use-expressns="true"時,則表示改成 SpEL 表達式。 SpEL 容許使用特定的訪問控制規則表達式語言。與簡單的字符串如 ROLE_USER 不一樣,配置文件能夠指明表達式語言觸發方法調用、引用系統屬性、計算機值等等。http標籤中的配置改成以下:
  <http auto-config="false" use-expressions="true">  
        <intercept-url pattern="/page/login.jsp" access="permitAll" />  
        <intercept-url pattern="/page/user.jsp" access="hasRole('ROLE_ADMIN')" />  
        <intercept-url pattern="/**" access="hasRole('ROLE_USER')" />  
        <form-login login-page="/page/login.jsp" default-target-url="/page/user.jsp" authentication-failure-url="/login.jsp?error=true" />  
        <logout invalidate-session="true" logout-success-url="/page/login.jsp" logout-url="/j_spring_security_logout"/>    
    </http>  
配置文件中的其餘配置在前面幾篇博客中都有詳細的講解,這裏就不贅述了。

三 、其餘文件

user.jspspring

<%@ 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>User Page</h1>
        <a href="${pageContext.request.contextPath}/j_spring_security_logout">退出登錄</a>  
    </body>
</html>

 

admin.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>Admin Page</h1>
        <a href="${pageContext.request.contextPath}/j_spring_security_logout">退出登錄</a>
    </body>
</html>

 

這裏定義了兩個頁面,user.jsp用戶和管理員均可以訪問,admin.jsp只有管理員能夠訪問,同時兩個頁面都有註銷按鈕,註銷按鈕提交的地址也就是上面配置文件中的地址/j_spring_security_logout。
pom.xml和前面章節的同樣
 
web.xml修改下默認頁面
<?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" 
    xmlns:web="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_3_0.xsd"
    version="3.0">
    <display-name>SpringSecurity</display-name>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring-*.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>/page/login.jsp</welcome-file>
  </welcome-file-list>
</web-app>

 

4、結果

 

 

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

 

當輸入管理員名和密碼,同時勾選2周不用登錄,驗證成功後,跳轉到user.jsp,同時adminPage.jsp也能夠訪問,這時把一個頁面關閉再從新訪問資源時,由於勾選2周不用登錄,因此能夠成功訪問;而後註銷,這是再訪問資源時,就會跳轉到登錄頁面,要求登錄才能訪問。瀏覽器

相關文章
相關標籤/搜索