天天看點

Spring boot +Spring Security + Thymeleaf 認證失敗傳回錯誤資訊

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

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+)

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)

groupId: <code>org.thymeleaf.extras</code>

artifactId:

Spring Security 3 integration package: <code>thymeleaf-extras-springsecurity3</code>

Spring Security 4 integration package: <code>thymeleaf-extras-springsecurity4</code>

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

New expression utility objects:

<code>#authentication</code> representing the Spring Security authentication object (an object implementing the <code>org.springframework.security.core.Authentication</code> interface).

<code>#authorization</code>: a expression utility object with methods for checking authorization based on expressions, URLs and Access Control Lists.

New attributes:

<code>sec:authentication="prop"</code> outputs a <code>prop</code> property of the authentication object, similar to the Spring Security <code>&lt;sec:authentication/&gt;</code> JSP tag.

<code>sec:authorize="expr"</code> or <code>sec:authorize-expr="expr"</code> renders the element children (tag content) if the authenticated user is authorized to see it according to the specified Spring Security expression.

<code>sec:authorize-url="url"</code> renders the element children (tag content) if the authenticated user is authorized to see the specified URL.

<code>sec:authorize-acl="object :: permissions"</code> 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.

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 <code>sec:*</code> attributes and special expression utility objects:

And that's all!

The <code>#authentication</code> object can be easily used, like this:

The <code>#authorization</code> object can be used in a similar way, normally in <code>th:if</code> or <code>th:unless</code>tags:

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

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

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

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

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

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

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

For specifying a specific HTTP method, do:

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.

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

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

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 + Thymeleaf 認證失敗傳回錯誤資訊

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

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

Spring boot +Spring Security + Thymeleaf 認證失敗傳回錯誤資訊

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

Spring boot +Spring Security + Thymeleaf 認證失敗傳回錯誤資訊

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

Spring boot +Spring Security + Thymeleaf 認證失敗傳回錯誤資訊

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

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

Spring boot +Spring Security + Thymeleaf 認證失敗傳回錯誤資訊

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

Spring boot +Spring Security + Thymeleaf 認證失敗傳回錯誤資訊
Spring boot +Spring Security + Thymeleaf 認證失敗傳回錯誤資訊

經過驗證,通過這樣設定,完美的解決了我遇到的問題,到現在,我仍沒有明白設定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