Spring Security 關(guān)于登錄

2018-09-28 19:17 更新

關(guān)于登錄

form-login 元素介紹

http 元素下的 form-login 元素是用來定義表單登錄信息的。當(dāng)我們什么屬性都不指定的時(shí)候 Spring Security 會為我們生成一個(gè)默認(rèn)的登錄頁面。如果不想使用默認(rèn)的登錄頁面,我們可以指定自己的登錄頁面。

使用自定義登錄頁面

自定義登錄頁面是通過 login-page 屬性來指定的。提到 login-page 我們不得不提另外幾個(gè)屬性。

  • username-parameter:表示登錄時(shí)用戶名使用的是哪個(gè)參數(shù),默認(rèn)是 “j_username”。
  • password-parameter:表示登錄時(shí)密碼使用的是哪個(gè)參數(shù),默認(rèn)是 “j_password”。
  • login-processing-url:表示登錄時(shí)提交的地址,默認(rèn)是 “/j-spring-security-check”。這個(gè)只是 Spring Security 用來標(biāo)記登錄頁面使用的提交地址,真正關(guān)于登錄這個(gè)請求是不需要用戶自己處理的。

所以,我們可以通過如下定義使 Spring Security 在需要用戶登錄時(shí)跳轉(zhuǎn)到我們自定義的登錄頁面。

   <security:http auto-config="true">
      <security:form-login login-page="/login.jsp"
         login-processing-url="/login.do" username-parameter="username"
         password-parameter="password" />
      <!-- 表示匿名用戶可以訪問 -->
      <security:intercept-url pattern="/login.jsp" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
      <security:intercept-url pattern="/**" access="ROLE_USER" />
   </security:http>

需要注意的是,我們之前配置的是所有的請求都需要 ROLE_USER 權(quán)限,這意味著我們自定義的 “/login.jsp” 也需要該權(quán)限,這樣就會形成一個(gè)死循環(huán)了。解決辦法是我們需要給 “/login.jsp” 放行。通過指定 “/login.jsp” 的訪問權(quán)限為 “IS_AUTHENTICATED_ANONYMOUSLY” 或 “ROLE_ANONYMOUS” 可以達(dá)到這一效果。此外,我們也可以通過指定一個(gè) http 元素的安全性為 none 來達(dá)到相同的效果。如:

   <security:http security="none" pattern="/login.jsp" />
   <security:http auto-config="true">
      <security:form-login login-page="/login.jsp"
         login-processing-url="/login.do" username-parameter="username"
         password-parameter="password" />
      <security:intercept-url pattern="/**" access="ROLE_USER" />
   </security:http>

它們兩者的區(qū)別是前者將進(jìn)入 Spring Security 定義的一系列用于安全控制的 filter,而后者不會。當(dāng)指定一個(gè) http 元素的 security 屬性為 none 時(shí),表示其對應(yīng) pattern 的 filter 鏈為空。從 3.1 開始,Spring Security 允許我們定義多個(gè) http 元素以滿足針對不同的 pattern 請求使用不能的 filter 鏈。當(dāng)為指定 pattern 屬性時(shí)表示對應(yīng)的 http 元素定義將對所有的請求發(fā)生作用。

根據(jù)上面的配置,我們自定義的登錄頁面的內(nèi)容應(yīng)該是這樣子的:

   <form action="login.do" method="post">
      <table>
         <tr>
            <td> 用戶名:</td>
            <td><input type="text" name="username"/></td>
         </tr>
         <tr>
            <td> 密碼:</td>
            <td><input type="password" name="password"/></td>
         </tr>
         <tr>
            <td colspan="2" align="center">
                <input type="submit" value=" 登錄 "/>
                <input type="reset" value=" 重置 "/>
            </td>
         </tr>
      </table>
   </form>

指定登錄后的頁面

通過 default-target-url 指定

默認(rèn)情況下,我們在登錄成功后會返回到原本受限制的頁面。但如果用戶是直接請求登錄頁面,登錄成功后應(yīng)該跳轉(zhuǎn)到哪里呢?默認(rèn)情況下它會跳轉(zhuǎn)到當(dāng)前應(yīng)用的根路徑,即歡迎頁面。通過指定 form-login 元素的 default-target-url 屬性,我們可以讓用戶在直接登錄后跳轉(zhuǎn)到指定的頁面。如果想讓用戶不管是直接請求登錄頁面,還是通過 Spring Security 引導(dǎo)過來的,登錄之后都跳轉(zhuǎn)到指定的頁面,我們可以通過指定 form-login 元素的 always-use-default-target 屬性為 true 來達(dá)到這一效果。

通過 authentication-success-handler-ref 指定

authentication-success-handler-ref 對應(yīng)一個(gè) AuthencticationSuccessHandler 實(shí)現(xiàn)類的引用。如果指定了 authentication-success-handler-ref,登錄認(rèn)證成功后會調(diào)用指定 AuthenticationSuccessHandler 的 onAuthenticationSuccess 方法。我們需要在該方法體內(nèi)對認(rèn)證成功做一個(gè)處理,然后返回對應(yīng)的認(rèn)證成功頁面。使用了 authentication-success-handler-ref 之后認(rèn)證成功后的處理就由指定的 AuthenticationSuccessHandler 來處理,之前的那些 default-target-url 之類的就都不起作用了。

以下是自定義的一個(gè) AuthenticationSuccessHandler 的實(shí)現(xiàn)類。

publicclass AuthenticationSuccessHandlerImpl implements
      AuthenticationSuccessHandler {

   publicvoid onAuthenticationSuccess(HttpServletRequest request,
         HttpServletResponse response, Authentication authentication)
         throws IOException, ServletException {
      response.sendRedirect(request.getContextPath());
   }

}

其對應(yīng)使用 authentication-success-handler-ref 屬性的配置是這樣的:

   <security:http auto-config="true">
      <security:form-login login-page="/login.jsp"
         login-processing-url="/login.do" username-parameter="username"
         password-parameter="password"
         authentication-success-handler-ref="authSuccess"/>
      <!-- 表示匿名用戶可以訪問 -->
      <security:intercept-url pattern="/login.jsp"
         access="IS_AUTHENTICATED_ANONYMOUSLY" />
      <security:intercept-url pattern="/**" access="ROLE_USER" />
   </security:http>
   <!-- 認(rèn)證成功后的處理類 -->
   <bean id="authSuccess" class="com.xxx.AuthenticationSuccessHandlerImpl"/>

指定登錄失敗后的頁面

除了可以指定登錄認(rèn)證成功后的頁面和對應(yīng)的 AuthenticationSuccessHandler 之外,form-login 同樣允許我們指定認(rèn)證失敗后的頁面和對應(yīng)認(rèn)證失敗后的處理器 AuthenticationFailureHandler。

通過 authentication-failure-url 指定

默認(rèn)情況下登錄失敗后會返回登錄頁面,我們也可以通過 form-login 元素的 authentication-failure-url 來指定登錄失敗后的頁面。需要注意的是登錄失敗后的頁面跟登錄頁面一樣也是需要配置成在未登錄的情況下可以訪問,否則登錄失敗后請求失敗頁面時(shí)又會被 Spring Security 重定向到登錄頁面。

   <security:http auto-config="true">
      <security:form-login login-page="/login.jsp"
         login-processing-url="/login.do" username-parameter="username"
         password-parameter="password"
         authentication-failure-url="/login_failure.jsp"
         />
      <!-- 表示匿名用戶可以訪問 -->
      <security:intercept-url pattern="/login*.jsp*"
         access="IS_AUTHENTICATED_ANONYMOUSLY" />
      <security:intercept-url pattern="/**" access="ROLE_USER" />
   </security:http>

通過 authentication-failure-handler-ref 指定

類似于 authentication-success-handler-ref,authentication-failure-handler-ref 對應(yīng)一個(gè)用于處理認(rèn)證失敗的 AuthenticationFailureHandler 實(shí)現(xiàn)類。指定了該屬性,Spring Security 在認(rèn)證失敗后會調(diào)用指定 AuthenticationFailureHandler 的 onAuthenticationFailure 方法對認(rèn)證失敗進(jìn)行處理,此時(shí) authentication-failure-url 屬性將不再發(fā)生作用。

http-basic

之前介紹的都是基于 form-login 的表單登錄,其實(shí) Spring Security 還支持彈窗進(jìn)行認(rèn)證。通過定義 http 元素下的 http-basic 元素可以達(dá)到這一效果。

   <security:http auto-config="true">
      <security:http-basic/>
      <security:intercept-url pattern="/**" access="ROLE_USER" />
   </security:http>

此時(shí),如果我們訪問受 Spring Security 保護(hù)的資源時(shí),系統(tǒng)將會彈出一個(gè)窗口來要求我們進(jìn)行登錄認(rèn)證。效果如下:

當(dāng)然此時(shí)我們的表單登錄也還是可以使用的,只不過當(dāng)我們訪問受包含資源的時(shí)候 Spring Security 不會自動跳轉(zhuǎn)到登錄頁面。這就需要我們自己去請求登錄頁面進(jìn)行登錄。

需要注意的是當(dāng)我們同時(shí)定義了 http-basic 和 form-login 元素時(shí),form-login 將具有更高的優(yōu)先級。即在需要認(rèn)證的時(shí)候 Spring Security 將引導(dǎo)我們到登錄頁面,而不是彈出一個(gè)窗口。

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號