Spring boot +Spring Security + Thymeleaf 認證失敗返回錯誤信息


 

[Please make sure to select the branch corresponding to the version of Thymeleaf you are using]

Status

This is a thymeleaf extras module, not a part of the Thymeleaf core (and as such following its own versioning schema), but fully supported by the Thymeleaf team.

This repository contains two projects:

  • thymeleaf-extras-springsecurity3 for integration with Spring Security 3.x
  • thymeleaf-extras-springsecurity4 for integration with Spring Security 4.x

Current versions:

  • Version 3.0.2.RELEASE - for Thymeleaf 3.0 (requires Thymeleaf 3.0.3+)
  • Version 2.1.3.RELEASE - for Thymeleaf 2.1 (requires Thymeleaf 2.1.2+)

License

This software is licensed under the [Apache License 2.0] (http://www.apache.org/licenses/LICENSE-2.0.html).

Requirements (3.0.x)

  • Thymeleaf 3.0.0+
  • Spring Framework version 3.0.x to 4.3.x
  • Spring Security version 3.0.x to 4.2.x
  • Web environment (Spring Security integration cannot work offline)

Maven info

  • groupId: org.thymeleaf.extras
  • artifactId:
  • Spring Security 3 integration package: thymeleaf-extras-springsecurity3
  • Spring Security 4 integration package: thymeleaf-extras-springsecurity4

Distribution packages

Distribution packages (binaries + sources + javadoc) can be downloaded from SourceForge.

Features

This module provides a new dialect called org.thymeleaf.extras.springsecurity3.dialect.SpringSecurityDialect or org.thymeleaf.extras.springsecurity4.dialect.SpringSecurityDialect (depending on the Spring Security version), with default prefix sec. It includes:

  • New expression utility objects:
  • #authentication representing the Spring Security authentication object (an object implementing the org.springframework.security.core.Authentication interface).
  • #authorization: a expression utility object with methods for checking authorization based on expressions, URLs and Access Control Lists.
  • New attributes:
  • sec:authentication="prop" outputs a prop property of the authentication object, similar to the Spring Security <sec:authentication/> JSP tag.
  • sec:authorize="expr" or sec:authorize-expr="expr" renders the element children (tag content) if the authenticated user is authorized to see it according to the specified Spring Security expression.
  • sec:authorize-url="url" renders the element children (tag content) if the authenticated user is authorized to see the specified URL.
  • sec:authorize-acl="object :: permissions" renders the element children (tag content) if the authenticated user has the specified permissions on the specified domain object, according to Spring Source's Access Control List system.

Configuration

In order to use the thymeleaf-extras-springsecurity3 or thymeleaf-extras-springsecurity4 modules in our Spring MVC application, we will first need to configure our application in the usual way for Spring + Thymeleaf applications (TemplateEngine bean, template resolvers, etc.), and add the SpringSecurity dialect to our Template Engine so that we can use the sec:* attributes and special expression utility objects:

    <bean id="templateEngine" class="org.thymeleaf.spring4.SpringTemplateEngine"> ... <property name="additionalDialects"> <set> <!-- Note the package would change to 'springsecurity3' if you are using that version --> <bean class="org.thymeleaf.extras.springsecurity4.dialect.SpringSecurityDialect"/> </set> </property> ... </bean>

And that's all!

Using the expression utility objects

The #authentication object can be easily used, like this:

    <div th:text="${#authentication.name}"> The value of the "name" property of the authentication object should appear here. </div>

The #authorization object can be used in a similar way, normally in th:if or th:unlesstags:

    <div th:if="${#authorization.expression('hasRole(''ROLE_ADMIN'')')}"> This will only be displayed if authenticated user has role ROLE_ADMIN. </div>

The #authorization object is an instance of org.thymeleaf.extras.springsecurity[3|4].auth.Authorization, see this class and its documentation to understand all the methods offered.

Using the attributes

Using the sec:authentication attribute is equivalent to using the #authentication object, but using its own attribute:

    <div sec:authentication="name"> The value of the "name" property of the authentication object should appear here. </div>

The sec:authorize and sec:authorize-expr attributes are exactly the same. They work equivalently to a th:if that evaluated an #authorization.expression(...) expression, by evaluating a Spring Security Expression:

    <div sec:authorize="hasRole('ROLE_ADMIN')"> This will only be displayed if authenticated user has role ROLE_ADMIN. </div>

These Spring Security Expressions in sec:authorize attributes are in fact Spring EL expressions evaluated on a SpringSecurity-specific root object containing methods such as hasRole(...)getPrincipal(), etc.

As with normal Spring EL expressions, Thymeleaf allows you to access a series of objects from them including the context variables map (the #vars object). In fact, you are allowed to surround your access expression with ${...} if it makes you feel more comfortable:

    <div sec:authorize="${hasRole(#vars.expectedRole)}"> This will only be displayed if authenticated user has a role computed by the controller. </div>

Remember that Spring Security sets a special security-oriented object as expression root, which is why you would not be able to access the expectedRole variable directly in the above expression.

Another way of checking authorization is sec:authorize-url, which allows you to check whether a user is authorized to visit a specific URL or not:

    <div sec:authorize-url="/admin"> This will only be displayed if authenticated user can call the "/admin" URL. </div>

For specifying a specific HTTP method, do:

    <div sec:authorize-url="POST /admin"> This will only be displayed if authenticated user can call the "/admin" URL using the POST HTTP method. </div>

Finally, there is an attribute for checking authorization using Spring Security's Access Control Lists, which needs the specification of a domain object and the permissions defined on it that we are asking for.

    <div sec:authorize-acl="${obj} :: '1,3'"> This will only be displayed if authenticated user has permissions "1" and "3" on domain object referenced by context variable "obj". </div>

In this attribute, both domain object and permission specifications are considered to be thymeleaf Standard Expressions.

Namespace

The namespace for both Spring 3 and 4 versions of this dialect is http://www.thymeleaf.org/extras/spring-security.

 <html xmlns:sec="http://www.thymeleaf.org/extras/spring-security">

Getting the namespace incorrect won't impact processing of your template. It might however impact your IDE when it comes to things like suggestions/auto-completion in your templates.

https://github.com/thymeleaf/thymeleaf-extras-springsecurity

 

 

spring boot以其眾多友誼的特性,如零配置、微服務等,吸引了很多的粉絲。而其與Spring Security安全框架的無縫結合,使其具備的安全的特性。在此基礎上使用Thymeleaf模板引擎進行渲染,靜動態結合,讓頁面開發更加簡單、直觀。

通過表單提交登錄的用戶名和密碼是登錄接口比較常見的一種設計。在初學的過程中,我也不例外的采用個這種方式。表單設計見下圖。

 

登錄成功,完成正常的主頁面跳轉,這個不存在問題。存在問題的是,登錄失敗了該咋辦呢?我就在考慮,由於thymeleaf的局部刷新操作,登錄失敗了將登錄失敗的異常信息顯示在登錄頁面,也就是表單上。於是,我的登錄設計又變成了如下圖所示的表單。

        

         通過這種方法,當登錄表單驗證失敗時,會該用戶顯示”用戶名或密碼錯誤,請重試”,這當然是比較好的,但是驗證失敗的情況不僅僅是用戶名或密碼錯誤吧,應該還有其它的情形,比較常見的就有,該用戶已被鎖定,該用戶不存在,請先注冊等。

那么該如何區分這么情形呢,怎么把登錄表單驗證失敗的比較詳細的狀況顯示給用戶呢。經過一段時間的調研,發現Spring boot提供了比較完美的解決方案,而其秘密就在Spring Security的配置中。我項目中的Spring Security配置如下圖所示。

 

而我在閱讀Spring Security源碼時,當認證失敗時,找尋到以下處理的代碼

 

而重點就在saveException函數,而此函數的具體代碼如下:

 

從這段代碼中,我們可以清晰的看到,認證失敗的異常信息被保存在Session中,如果我們可以讀取Session中的信息那么,之前所遇到的問題就迎刃而解了吧。

事實上,事物的發展從來不是一帆風順的,解決問題也是類似。我了解到Thymeleaf提供了讀取緩存Session的方案,就迫不及待的進行嘗試,於是乎,我的登錄表單又變成了如下模樣,紅線指出的是Thymleaf緩存的讀取方式。

 

這樣就可以顯示驗證失敗的具體信息了嗎?經過我的測試,我發現,此信息是未定義。也就是說,模樣讀取到緩存中的信息。

通過在網上查找資料,我在浩瀚的百度的犄角旮旯里,查找到以下的代碼片段。

 

         我如獲至寶,仿佛見到了光明。在配置文件配置的時代,可以設置登錄失敗的跳轉頁面為”/login.html?error=true”,而我設置的是“/login?error”,那么是否可以設置為類似的true呢?我迫不及待的進行嘗試。於是乎,我Spring Security的Java Config又變成了如下的樣子。

 

經過驗證,通過這樣設置,完美的解決了我遇到的問題,到現在,我仍沒有明白設置true的含義,望知道的讀者可以告訴小編。

小編來總結哈,在Spring boot +Spring Security + Thymeleaf框架下,通過用戶名/密碼表單提交,在登錄界面獲取異常信息的步驟,主要有以下兩點:

其一:將登錄失敗的url設置為”/login?error=true”(即后綴帶?error=true),使前端的thymleaf可以讀取Session;

其二:Thymeleaf提供的讀取緩存中信息的方法${session.SPRING_SECURITY_LAST_EXCEPTION.message},兩者缺一不可。

 

http://blog.csdn.net/sun1021873926/article/details/60332059

 


免責聲明!

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



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