欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
Spring源代碼解析(十):Spring Acegi框架授權的實(shí)現
Java代碼
  1. //這里是攔截器攔截HTTP請求的入口   
  2.     public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)   
  3.         throws IOException, ServletException {   
  4.         FilterInvocation fi = new FilterInvocation(request, response, chain);   
  5.         invoke(fi);   
  6.     }   
  7. //這是具體的攔截調用   
  8.     public void invoke(FilterInvocation fi) throws IOException, ServletException {   
  9.         if ((fi.getRequest() != null) && (fi.getRequest().getAttribute(FILTER_APPLIED) != null)   
  10.             && observeOncePerRequest) {   
  11.            //在第一次進(jìn)行過(guò)安全檢查之后就不會(huì )再做了   
  12.             fi.getChain().doFilter(fi.getRequest(), fi.getResponse());   
  13.         } else {   
  14.             //這是第一次收到相應的請求,需要做安全檢測,同時(shí)把標志為設置好 -  FILTER_APPLIED,下次就再有請求就不會(huì )作相同的安全檢查了   
  15.             if (fi.getRequest() != null) {   
  16.                 fi.getRequest().setAttribute(FILTER_APPLIED, Boolean.TRUE);   
  17.             }   
  18.             //這里是做安全檢查的地方   
  19.             InterceptorStatusToken token = super.beforeInvocation(fi);   
  20.             //接著(zhù)向攔截器鏈執行   
  21.             try {   
  22.                 fi.getChain().doFilter(fi.getRequest(), fi.getResponse());   
  23.             } finally {   
  24.                 super.afterInvocation(token, null);   
  25.             }   
  26.         }   
  27.     }  
//這里是攔截器攔截HTTP請求的入口public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {FilterInvocation fi = new FilterInvocation(request, response, chain);invoke(fi);}//這是具體的攔截調用public void invoke(FilterInvocation fi) throws IOException, ServletException {if ((fi.getRequest() != null) && (fi.getRequest().getAttribute(FILTER_APPLIED) != null)&& observeOncePerRequest) {//在第一次進(jìn)行過(guò)安全檢查之后就不會(huì )再做了fi.getChain().doFilter(fi.getRequest(), fi.getResponse());} else {//這是第一次收到相應的請求,需要做安全檢測,同時(shí)把標志為設置好 -  FILTER_APPLIED,下次就再有請求就不會(huì )作相同的安全檢查了if (fi.getRequest() != null) {fi.getRequest().setAttribute(FILTER_APPLIED, Boolean.TRUE);}//這里是做安全檢查的地方InterceptorStatusToken token = super.beforeInvocation(fi);//接著(zhù)向攔截器鏈執行try {fi.getChain().doFilter(fi.getRequest(), fi.getResponse());} finally {super.afterInvocation(token, null);}}}


我們看看在A(yíng)bstractSecurityInterceptor是怎樣對HTTP請求作安全檢測的:

Java代碼
  1. protected InterceptorStatusToken beforeInvocation(Object object) {   
  2.     Assert.notNull(object, "Object was null");   
  3.   
  4.     if (!getSecureObjectClass().isAssignableFrom(object.getClass())) {   
  5.         throw new IllegalArgumentException("Security invocation attempted for object "  
  6.             + object.getClass().getName()   
  7.             + " but AbstractSecurityInterceptor only configured to support secure objects of type: "  
  8.             + getSecureObjectClass());   
  9.     }   
  10.     //這里讀取配置FilterSecurityInterceptor的ObjectDefinitionSource屬性,這些屬性配置了資源的安全設置   
  11.     ConfigAttributeDefinition attr = this.obtainObjectDefinitionSource().getAttributes(object);   
  12.   
  13.     if (attr == null) {   
  14.         if(rejectPublicInvocations) {   
  15.             throw new IllegalArgumentException(   
  16.                   "No public invocations are allowed via this AbstractSecurityInterceptor. "  
  17.                 + "This indicates a configuration error because the "  
  18.                 + "AbstractSecurityInterceptor.rejectPublicInvocations property is set to 'true'");   
  19.         }   
  20.   
  21.         if (logger.isDebugEnabled()) {   
  22.             logger.debug("Public object - authentication not attempted");   
  23.         }   
  24.   
  25.         publishEvent(new PublicInvocationEvent(object));   
  26.   
  27.         return null// no further work post-invocation   
  28.     }   
  29.   
  30.   
  31.     if (logger.isDebugEnabled()) {   
  32.         logger.debug("Secure object: " + object.toString() + "; ConfigAttributes: " + attr.toString());   
  33.     }   
  34.     //這里從SecurityContextHolder中去取Authentication對象,一般在登錄時(shí)會(huì )放到SecurityContextHolder中去   
  35.     if (SecurityContextHolder.getContext().getAuthentication() == null) {   
  36.         credentialsNotFound(messages.getMessage("AbstractSecurityInterceptor.authenticationNotFound",   
  37.                 "An Authentication object was not found in the SecurityContext"), object, attr);   
  38.     }   
  39.   
  40.     // 如果前面沒(méi)有處理鑒權,這里需要對鑒權進(jìn)行處理   
  41.     Authentication authenticated;   
  42.   
  43.     if (!SecurityContextHolder.getContext().getAuthentication().isAuthenticated() || alwaysReauthenticate) {   
  44.         try {//調用配置好的AuthenticationManager處理鑒權,如果鑒權不成功,拋出異常結束處理   
  45.             authenticated = this.authenticationManager.authenticate(SecurityContextHolder.getContext()   
  46.                                                                                          .getAuthentication());   
  47.         } catch (AuthenticationException authenticationException) {   
  48.             throw authenticationException;   
  49.         }   
  50.   
  51.         // We don't authenticated.setAuthentication(true), because each provider should do that   
  52.         if (logger.isDebugEnabled()) {   
  53.             logger.debug("Successfully Authenticated: " + authenticated.toString());   
  54.         }   
  55.         //這里把鑒權成功后得到的Authentication保存到SecurityContextHolder中供下次使用   
  56.         SecurityContextHolder.getContext().setAuthentication(authenticated);   
  57.     } else {//這里處理前面已經(jīng)通過(guò)鑒權的請求,先從SecurityContextHolder中去取得Authentication   
  58.         authenticated = SecurityContextHolder.getContext().getAuthentication();   
  59.   
  60.         if (logger.isDebugEnabled()) {   
  61.             logger.debug("Previously Authenticated: " + authenticated.toString());   
  62.         }   
  63.     }   
  64.   
  65.     // 這是處理授權的過(guò)程   
  66.     try {   
  67.         //調用配置好的AccessDecisionManager來(lái)進(jìn)行授權   
  68.         this.accessDecisionManager.decide(authenticated, object, attr);   
  69.     } catch (AccessDeniedException accessDeniedException) {   
  70.         //授權不成功向外發(fā)布事件   
  71.         AuthorizationFailureEvent event = new AuthorizationFailureEvent(object, attr, authenticated,   
  72.                 accessDeniedException);   
  73.         publishEvent(event);   
  74.   
  75.         throw accessDeniedException;   
  76.     }   
  77.   
  78.     if (logger.isDebugEnabled()) {   
  79.         logger.debug("Authorization successful");   
  80.     }   
  81.   
  82.     AuthorizedEvent event = new AuthorizedEvent(object, attr, authenticated);   
  83.     publishEvent(event);   
  84.   
  85.     // 這里構建一個(gè)RunAsManager來(lái)替代當前的Authentication對象,默認情況下使用的是NullRunAsManager會(huì )把SecurityContextHolder中的Authentication對象清空   
  86.     Authentication runAs = this.runAsManager.buildRunAs(authenticated, object, attr);   
  87.   
  88.     if (runAs == null) {   
  89.         if (logger.isDebugEnabled()) {   
  90.             logger.debug("RunAsManager did not change Authentication object");   
  91.         }   
  92.   
  93.         // no further work post-invocation   
  94.         return new InterceptorStatusToken(authenticated, false, attr, object);   
  95.     } else {   
  96.         if (logger.isDebugEnabled()) {   
  97.             logger.debug("Switching to RunAs Authentication: " + runAs.toString());   
  98.         }   
  99.   
  100.         SecurityContextHolder.getContext().setAuthentication(runAs);   
  101.   
  102.         // revert to token.Authenticated post-invocation   
  103.         return new InterceptorStatusToken(authenticated, true, attr, object);   
  104.     }   
  105. }  
    protected InterceptorStatusToken beforeInvocation(Object object) {Assert.notNull(object, "Object was null");if (!getSecureObjectClass().isAssignableFrom(object.getClass())) {throw new IllegalArgumentException("Security invocation attempted for object "+ object.getClass().getName()+ " but AbstractSecurityInterceptor only configured to support secure objects of type: "+ getSecureObjectClass());}//這里讀取配置FilterSecurityInterceptor的ObjectDefinitionSource屬性,這些屬性配置了資源的安全設置ConfigAttributeDefinition attr = this.obtainObjectDefinitionSource().getAttributes(object);if (attr == null) {if(rejectPublicInvocations) {throw new IllegalArgumentException("No public invocations are allowed via this AbstractSecurityInterceptor. "+ "This indicates a configuration error because the "+ "AbstractSecurityInterceptor.rejectPublicInvocations property is set to 'true'");}if (logger.isDebugEnabled()) {logger.debug("Public object - authentication not attempted");}publishEvent(new PublicInvocationEvent(object));return null; // no further work post-invocation}if (logger.isDebugEnabled()) {logger.debug("Secure object: " + object.toString() + "; ConfigAttributes: " + attr.toString());}//這里從SecurityContextHolder中去取Authentication對象,一般在登錄時(shí)會(huì )放到SecurityContextHolder中去if (SecurityContextHolder.getContext().getAuthentication() == null) {credentialsNotFound(messages.getMessage("AbstractSecurityInterceptor.authenticationNotFound","An Authentication object was not found in the SecurityContext"), object, attr);}// 如果前面沒(méi)有處理鑒權,這里需要對鑒權進(jìn)行處理Authentication authenticated;if (!SecurityContextHolder.getContext().getAuthentication().isAuthenticated() || alwaysReauthenticate) {try {//調用配置好的AuthenticationManager處理鑒權,如果鑒權不成功,拋出異常結束處理authenticated = this.authenticationManager.authenticate(SecurityContextHolder.getContext().getAuthentication());} catch (AuthenticationException authenticationException) {throw authenticationException;}// We don't authenticated.setAuthentication(true), because each provider should do thatif (logger.isDebugEnabled()) {logger.debug("Successfully Authenticated: " + authenticated.toString());}//這里把鑒權成功后得到的Authentication保存到SecurityContextHolder中供下次使用SecurityContextHolder.getContext().setAuthentication(authenticated);} else {//這里處理前面已經(jīng)通過(guò)鑒權的請求,先從SecurityContextHolder中去取得Authenticationauthenticated = SecurityContextHolder.getContext().getAuthentication();if (logger.isDebugEnabled()) {logger.debug("Previously Authenticated: " + authenticated.toString());}}// 這是處理授權的過(guò)程try {//調用配置好的AccessDecisionManager來(lái)進(jìn)行授權this.accessDecisionManager.decide(authenticated, object, attr);} catch (AccessDeniedException accessDeniedException) {//授權不成功向外發(fā)布事件AuthorizationFailureEvent event = new AuthorizationFailureEvent(object, attr, authenticated,accessDeniedException);publishEvent(event);throw accessDeniedException;}if (logger.isDebugEnabled()) {logger.debug("Authorization successful");}AuthorizedEvent event = new AuthorizedEvent(object, attr, authenticated);publishEvent(event);// 這里構建一個(gè)RunAsManager來(lái)替代當前的Authentication對象,默認情況下使用的是NullRunAsManager會(huì )把SecurityContextHolder中的Authentication對象清空Authentication runAs = this.runAsManager.buildRunAs(authenticated, object, attr);if (runAs == null) {if (logger.isDebugEnabled()) {logger.debug("RunAsManager did not change Authentication object");}// no further work post-invocationreturn new InterceptorStatusToken(authenticated, false, attr, object);} else {if (logger.isDebugEnabled()) {logger.debug("Switching to RunAs Authentication: " + runAs.toString());}SecurityContextHolder.getContext().setAuthentication(runAs);// revert to token.Authenticated post-invocationreturn new InterceptorStatusToken(authenticated, true, attr, object);}}


到這里我們假設配置AffirmativeBased作為AccessDecisionManager:

Java代碼
  1. //這里定義了決策機制,需要全票才能通過(guò)   
  2.     public void decide(Authentication authentication, Object object, ConfigAttributeDefinition config)   
  3.         throws AccessDeniedException {   
  4.         //這里取得配置好的迭代器集合   
  5.         Iterator iter = this.getDecisionVoters().iterator();   
  6.         int deny = 0;   
  7.         //依次使用各個(gè)投票器進(jìn)行投票,并對投票結果進(jìn)行計票   
  8.         while (iter.hasNext()) {   
  9.             AccessDecisionVoter voter = (AccessDecisionVoter) iter.next();   
  10.             int result = voter.vote(authentication, object, config);   
  11.             //這是對投票結果進(jìn)行處理,如果遇到其中一票通過(guò),那就授權通過(guò),如果是棄權或者反對,那就繼續投票   
  12.             switch (result) {   
  13.             case AccessDecisionVoter.ACCESS_GRANTED:   
  14.                 return;   
  15.   
  16.             case AccessDecisionVoter.ACCESS_DENIED:   
  17.             //這里對反對票進(jìn)行計數   
  18.                 deny++;   
  19.   
  20.                 break;   
  21.   
  22.             default:   
  23.                 break;   
  24.             }   
  25.         }   
  26.         //如果有反對票,拋出異常,整個(gè)授權不通過(guò)   
  27.         if (deny > 0) {   
  28.             throw new AccessDeniedException(messages.getMessage("AbstractAccessDecisionManager.accessDenied",   
  29.                     "Access is denied"));   
  30.         }   
  31.   
  32.         // 這里對棄權票進(jìn)行處理,看看是全是棄權票的決定情況,默認是不通過(guò),由allowIfAllAbstainDecisions變量控制   
  33.         checkAllowIfAllAbstainDecisions();   
  34.     }   
  35. 具體的投票由投票器進(jìn)行,我們這里配置了RoleVoter來(lái)進(jìn)行投票:   
  36.     public int vote(Authentication authentication, Object object, ConfigAttributeDefinition config) {   
  37.         int result = ACCESS_ABSTAIN;   
  38.         //這里取得資源的安全配置   
  39.         Iterator iter = config.getConfigAttributes();   
  40.   
  41.         while (iter.hasNext()) {   
  42.             ConfigAttribute attribute = (ConfigAttribute) iter.next();   
  43.                
  44.             if (this.supports(attribute)) {   
  45.                 result = ACCESS_DENIED;   
  46.   
  47.                 // 這里對資源配置的安全授權級別進(jìn)行判斷,也就是匹配ROLE為前綴的角色配置   
  48.                 // 遍歷每個(gè)配置屬性,如果其中一個(gè)匹配該主體持有的GrantedAuthority,則訪(fǎng)問(wèn)被允許。   
  49.                 for (int i = 0; i < authentication.getAuthorities().length; i++) {   
  50.                     if (attribute.getAttribute().equals(authentication.getAuthorities()[i].getAuthority())) {   
  51.                         return ACCESS_GRANTED;   
  52.                     }   
  53.                 }   
  54.             }   
  55.         }   
  56.   
  57.         return result;   
  58.     }  
//這里定義了決策機制,需要全票才能通過(guò)public void decide(Authentication authentication, Object object, ConfigAttributeDefinition config)throws AccessDeniedException {//這里取得配置好的迭代器集合Iterator iter = this.getDecisionVoters().iterator();int deny = 0;//依次使用各個(gè)投票器進(jìn)行投票,并對投票結果進(jìn)行計票while (iter.hasNext()) {AccessDecisionVoter voter = (AccessDecisionVoter) iter.next();int result = voter.vote(authentication, object, config);//這是對投票結果進(jìn)行處理,如果遇到其中一票通過(guò),那就授權通過(guò),如果是棄權或者反對,那就繼續投票switch (result) {case AccessDecisionVoter.ACCESS_GRANTED:return;case AccessDecisionVoter.ACCESS_DENIED://這里對反對票進(jìn)行計數deny++;break;default:break;}}//如果有反對票,拋出異常,整個(gè)授權不通過(guò)if (deny > 0) {throw new AccessDeniedException(messages.getMessage("AbstractAccessDecisionManager.accessDenied","Access is denied"));}// 這里對棄權票進(jìn)行處理,看看是全是棄權票的決定情況,默認是不通過(guò),由allowIfAllAbstainDecisions變量控制checkAllowIfAllAbstainDecisions();}具體的投票由投票器進(jìn)行,我們這里配置了RoleVoter來(lái)進(jìn)行投票:public int vote(Authentication authentication, Object object, ConfigAttributeDefinition config) {int result = ACCESS_ABSTAIN;//這里取得資源的安全配置Iterator iter = config.getConfigAttributes();while (iter.hasNext()) {ConfigAttribute attribute = (ConfigAttribute) iter.next();if (this.supports(attribute)) {result = ACCESS_DENIED;// 這里對資源配置的安全授權級別進(jìn)行判斷,也就是匹配ROLE為前綴的角色配置// 遍歷每個(gè)配置屬性,如果其中一個(gè)匹配該主體持有的GrantedAuthority,則訪(fǎng)問(wèn)被允許。for (int i = 0; i < authentication.getAuthorities().length; i++) {if (attribute.getAttribute().equals(authentication.getAuthorities()[i].getAuthority())) {return ACCESS_GRANTED;}}}}return result;}


上面就是對整個(gè)授權過(guò)程的一個(gè)分析,從FilterSecurityInterceptor攔截Http請求入手,然后讀取對資源的安全配置以后,把這些信息交由AccessDecisionManager來(lái)進(jìn)行決策,Spring為我們提供了若干決策器來(lái)使用,在決策器中我們可以配置投票器來(lái)完成投票,我們在上面具體分析了角色投票器的使用過(guò)程。

本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
學(xué)習acegi-security - bulain - ITeye技術(shù)網(wǎng)站
Spring Security3源碼分析-FilterSecurityInterceptor
spring事務(wù)回滾問(wèn)題
如何使用HttpClient認證機制
源碼分析shiro認證授權流程
spring security remember me 功能
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久