差異處

這裏顯示兩個版本的差異處。

連向這個比對檢視

Both sides previous revision 前次修改
下次修改
前次修改
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"​ >
行 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~~
 +