Spring Security教程(四)

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

自定義頁面

login.jsp:java

<%@ 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>複製代碼

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

springsecurityrememberme,選擇是否容許自動登陸的參數名稱。能夠直接把這個參數設置爲一個checkbox,無需設置value,Spring Security會自行判斷它是否被選中,這也是security內部提供的,只須要配置,不須要本身實現。spring

配置制定的頁面

配置文件以下:sql

<?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>複製代碼

說明:express

  • form-login這個標籤是配置登錄頁面的,其中的屬性login-page是配置登錄頁面的,default-target-url配置登錄成功後跳轉到的頁面,authentication-failure-url配置認證失敗後的跳轉頁面。
  • 在上面的配置中,登錄頁面確定是不能攔截的,任何人都應該能夠訪問, 配置表示容許匿名用戶訪問,就是不用身份均可以訪問;還有另外一種配置方式: ,這種配置達到的目的都是同樣的。
  • logout這個標籤用來配置退出或者註銷,其中的屬性invalidate-session,配置否是要清除session,logout-success-url配置註銷成功後的跳轉頁面,logout-url提交退出或者註銷的地址,所以咱們在配置退出或者註銷的時候,只須要將url設置爲/jspringsecurity_logout便可,這個地址也是security內部實現了的。
  • form-login標籤中還有一個特別要注意的屬性use-expressions,若是設置爲true,這配置access就要作相應的改變,不然項目啓動的時候會報錯,錯誤以下:

file

  • 若是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.jspsession

<%@ 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只有管理員能夠訪問,同時兩個頁面都有註銷按鈕,註銷按鈕提交的地址也就是上面配置文件中的地址/jspringsecurity_logout。pom.xml和前面的同樣,這裏就不貼了。jsp

結果

file

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

file

當輸入管理員名和密碼,同時勾選2周不用登錄,驗證成功後,跳轉到index.jsp,同時adminPage.jsp也能夠訪問,這時把一個頁面關閉再從新訪問資源時,由於勾選2周不用登錄,因此能夠成功訪問;而後註銷,這是再訪問資源時,就會跳轉到登錄頁面,要求登錄才能訪問。微信公衆號關注:ByteZ,獲取更多學習資料

file

相關文章
相關標籤/搜索