差異處
這裏顯示兩個版本的差異處。
下次修改 | 前次修改 | ||
java:spring:rest:auth_conflict_of_oauth2 [2016/01/26 18:37] tony 建立 |
java:spring:rest:auth_conflict_of_oauth2 [2023/06/25 09:48] (目前版本) |
||
---|---|---|---|
行 1: | 行 1: | ||
{{tag>java spring rest}} | {{tag>java spring rest}} | ||
- | ====== REST Auth使用OAuth2所發生的衝突 ====== | + | ====== REST使用OAuth2認證所發生的衝突 ====== |
===== Problem ===== | ===== Problem ===== | ||
- | 我們的Web App提供了Web Console與Rest API兩種介面。最近發現透過瀏覽器登入Web Console後,再去做Rest API的登入認證,會造成Web Console登出的問題。 | + | 我們的Web App提供了Web Console與Rest API兩種介面。最近發現在同一瀏覽器中,一個tab登入Web Console,另一個tab做Rest API的登入認證後,會使得Web Console發生登出或取不到認證資訊的問題。 |
===== How to resolve? ===== | ===== How to resolve? ===== | ||
- | 經過Trace發現是由於在before PRE_AUTH_FILTER階段,會經過OAuth2的Resource Server Filter: | + | 經過Trace發現是由於在Security Filter的before PRE_AUTH_FILTER階段,會經過OAuth2的Resource Server Filter: |
<code xml> | <code xml> | ||
<http name="api" pattern="/api/**" create-session="never" > | <http name="api" pattern="/api/**" create-session="never" > | ||
行 14: | 行 14: | ||
</http> | </http> | ||
</code> | </code> | ||
- | 從OAuth2AuthenticationProcessingFilter程式碼可以得知,如果在同一個session中已經過認證,則此Filter會清空SecurityContext: | + | 從OAuth2AuthenticationProcessingFilter程式碼可以得知,如果在同一個session中已經過認證,則此Filter會清空SecurityContext:\\ |
{{:java:spring:rest:rest_oauth2_filter.png?600|}}\\ | {{:java:spring:rest:rest_oauth2_filter.png?600|}}\\ | ||
而OAuth2AuthenticationProcessingFilter又提供了stateless設置,讓你可以在發生此問題時,不去清掉它。而在spring-security-oauth2 2.0.8版本後,設定檔是支援此屬性設置的: | 而OAuth2AuthenticationProcessingFilter又提供了stateless設置,讓你可以在發生此問題時,不去清掉它。而在spring-security-oauth2 2.0.8版本後,設定檔是支援此屬性設置的: | ||
行 21: | 行 21: | ||
token-services-ref="tokenServices" entry-point ref="oauthAuthenticationEntryPoint"/> | token-services-ref="tokenServices" entry-point ref="oauthAuthenticationEntryPoint"/> | ||
</code> | </code> | ||
- | 如此一來,當經過此Filter時,就會自動略過往下一個Filter去了。 | + | 如此一來,當經過此Filter時,就會自動略過往下一個Filter去了。另外還有一個相關問題是: 在同一browser請求的url中包含access_token。這會讓OAuth2AuthenticationProcessingFilter拿這access_token做驗證,驗證失敗就會清session而產生一樣問題。這問題需要思考的是: 如果使用者輸入錯誤的access_token,但同一session已經認證過了,是要顯示access_token錯誤,還是要讓使用者可以存取呢? |
+ | * 顯示access_token錯誤: 如果要顯示錯誤,又不想清掉session,那你就需要override OAuth2AuthenticationProcessingFilter。 | ||
+ | * 讓使用者可以存取: override TokenExtractor,讓它回傳null認證內容,以忽略認證。 | ||
+ | 我們考量到此問題發生機率很低,而且一般會操作Rest API都是透過寫程式,因此採用第二種做法。 | ||
+ | <code xml> | ||
+ | <oauth2:resource-server id="resourceServerFilter" token-extractor-ref="tokenExtractor" | ||
+ | stateless="false" token-services-ref="tokenServices" entry-point-ref="oauthAuthenticationEntryPoint"/> | ||
+ | <b:bean id="tokenExtractor" | ||
+ | class="org.tonylin.web.rest.oauth.TokenExtractor"/> | ||
+ | </code> | ||
+ | |||
+ | <code java> | ||
+ | public class TokenExtractor extends BearerTokenExtractor { | ||
+ | |||
+ | private boolean isAuthenticated() { | ||
+ | Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); | ||
+ | if (authentication == null || authentication instanceof AnonymousAuthenticationToken) { | ||
+ | return false; | ||
+ | } | ||
+ | return true; | ||
+ | } | ||
+ | |||
+ | @Override | ||
+ | public Authentication extract(HttpServletRequest request) { | ||
+ | if( isAuthenticated() ) | ||
+ | return null; | ||
+ | return super.extract(request); | ||
+ | } | ||
+ | |||
+ | } | ||
+ | </code> | ||
===== Reference ===== | ===== Reference ===== | ||
* [[https://github.com/spring-projects/spring-security-oauth/commit/36deb5e104f57e9c0740eeb717843c7f17f0af7c|oauth2 Lib提供stateless設置]] | * [[https://github.com/spring-projects/spring-security-oauth/commit/36deb5e104f57e9c0740eeb717843c7f17f0af7c|oauth2 Lib提供stateless設置]] | ||
行 29: | 行 59: | ||
* [[http://csns.calstatela.edu/wiki/content/cysun/notes/spring_security_filters|Understand Spring Security Filters]] | * [[http://csns.calstatela.edu/wiki/content/cysun/notes/spring_security_filters|Understand Spring Security Filters]] | ||
* [[https://github.com/spring-projects/spring-security-oauth/blob/master/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationProcessingFilter.java|OAuth2AuthenticationProcessingFilter.java]] | * [[https://github.com/spring-projects/spring-security-oauth/blob/master/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationProcessingFilter.java|OAuth2AuthenticationProcessingFilter.java]] | ||
+ | |||
+ | ===== ===== | ||
+ | ---- | ||
+ | \\ | ||
+ | ~~DISQUS~~ | ||
+ |