欢迎来到淘文阁 - 分享文档赚钱的网站! | 帮助中心 好文档才是您的得力助手!
淘文阁 - 分享文档赚钱的网站
全部分类
  • 研究报告>
  • 管理文献>
  • 标准材料>
  • 技术资料>
  • 教育专区>
  • 应用文书>
  • 生活休闲>
  • 考试试题>
  • pptx模板>
  • 工商注册>
  • 期刊短文>
  • 图片设计>
  • ImageVerifierCode 换一换

    Spring源代码解析(十):Spring Acegi框架授权的实现.doc

    • 资源ID:33829640       资源大小:83KB        全文页数:7页
    • 资源格式: DOC        下载积分:15金币
    快捷下载 游客一键下载
    会员登录下载
    微信登录下载
    三方登录下载: 微信开放平台登录   QQ登录  
    二维码
    微信扫一扫登录
    下载资源需要15金币
    邮箱/手机:
    温馨提示:
    快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。
    如填写123,账号就是123,密码也是123。
    支付方式: 支付宝    微信支付   
    验证码:   换一换

     
    账号:
    密码:
    验证码:   换一换
      忘记密码?
        
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
    5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

    Spring源代码解析(十):Spring Acegi框架授权的实现.doc

    如有侵权,请联系网站删除,仅供学习与交流Spring源代码解析(十):Spring Acegi框架授权的实现【精品文档】第 7 页Spring源代码解析(十):Spring Acegi框架授权的实现我们从FilterSecurityInterceptor我们从入手看看怎样进行授权的: 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.     public void invoke(FilterInvocation fi) throws IOException, ServletException    8.         if (fi.getRequest() != null) && (fi.getRequest().getAttribute(FILTER_APPLIED) != null)   9.             && observeOncePerRequest)    10.            /在第一次进行过安全检查之后就不会再做了   11.             fi.getChain().doFilter(fi.getRequest(), fi.getResponse();   12.          else    13.             /这是第一次收到相应的请求,需要做安全检测,同时把标志为设置好 -  FILTER_APPLIED,下次就再有请求就不会作相同的安全检查了   14.             if (fi.getRequest() != null)    15.                 fi.getRequest().setAttribute(FILTER_APPLIED, Boolean.TRUE);   16.             /这里是做安全检查的地方   17.             InterceptorStatusToken token = super.beforeInvocation(fi);   18.             /接着向拦截器链执行   19.             try    20.                 fi.getChain().doFilter(fi.getRequest(), fi.getResponse();   21.              finally    22.                 super.afterInvocation(token, null);   TTP请求的入口 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) /在第一次进行过安全检查之后就不会再做了 fi.getChain().doFilter(fi.getRequest(), fi.getResponse(); else /这是第一次收到相应的请求,需要做安全检测,同时把标志为设置好 - FILTER_APPLIED,下次就再有请求就不会作相同的安全检查了 if (fi.getRequest() != null) fi.getRequest().setAttribute(FILTER_APPLIED, Boolean.TRUE); /这里是做安全检查的地方 InterceptorStatusToken token = super.beforeInvocation(fi); /接着向拦截器链执行 try fi.getChain().doFilter(fi.getRequest(), fi.getResponse(); finally super.afterInvocation(token, null);我们看看在AbstractSecurityInterceptor是怎样对HTTP请求作安全检测的: Java代码 1. protected InterceptorStatusToken beforeInvocation(Object object)    2.     Assert.notNull(object, "Object was null");   3.     if (!getSecureObjectClass().isAssignableFrom(object.getClass()    4.         throw new IllegalArgumentException("Security invocation attempted for object "  5.             + object.getClass().getName()   6.             + " but AbstractSecurityInterceptor only configured to support secure objects of type: "  7.             + getSecureObjectClass();   8.     /这里读取配置FilterSecurityInterceptor的ObjectDefinitionSource属性,这些属性配置了资源的安全设置   9.     ConfigAttributeDefinition attr = this.obtainObjectDefinitionSource().getAttributes(object);   10.     if (attr = null)    11.         if(rejectPublicInvocations)    12.             throw new IllegalArgumentException(   13.                   "No public invocations are allowed via this AbstractSecurityInterceptor. "  14.                 + "This indicates a configuration error because the "  15.                 + "AbstractSecurityInterceptor.rejectPublicInvocations property is set to 'true'");   16.         if (logger.isDebugEnabled()    17.             logger.debug("Public object - authentication not attempted");   18.         publishEvent(new PublicInvocationEvent(object);   19.         return null; / no further work post-invocation   20.     if (logger.isDebugEnabled()    21.         logger.debug("Secure object: " + object.toString() + " ConfigAttributes: " + attr.toString();   22.     /这里从SecurityContextHolder中去取Authentication对象,一般在登录时会放到SecurityContextHolder中去   23.     if (SecurityContextHolder.getContext().getAuthentication() = null)    24.         credentialsNotFound(messages.getMessage("AbstractSecurityInterceptor.authenticationNotFound",   25.                 "An Authentication object was not found in the SecurityContext"), object, attr);   26.     / 如果前面没有处理鉴权,这里需要对鉴权进行处理   27.     Authentication authenticated;   28.     if (!SecurityContextHolder.getContext().getAuthentication().isAuthenticated() | alwaysReauthenticate)    29.         try /调用配置好的AuthenticationManager处理鉴权,如果鉴权不成功,抛出异常结束处理   30.             authenticated = this.authenticationManager.authenticate(SecurityContextHolder.getContext()   31.                                                                                          .getAuthentication();   32.          catch (AuthenticationException authenticationException)    33.             throw authenticationException;   34.         / We don't authenticated.setAuthentication(true), because each provider should do that   35.         if (logger.isDebugEnabled()    36.             logger.debug("Successfully Authenticated: " + authenticated.toString();   37.         /这里把鉴权成功后得到的Authentication保存到SecurityContextHolder中供下次使用   38.         SecurityContextHolder.getContext().setAuthentication(authenticated);   39.      else /这里处理前面已经通过鉴权的请求,先从SecurityContextHolder中去取得Authentication   40.         authenticated = SecurityContextHolder.getContext().getAuthentication();   41.         if (logger.isDebugEnabled()    42.             logger.debug("Previously Authenticated: " + authenticated.toString();   43.     / 这是处理授权的过程   44.     try    45.         /调用配置好的AccessDecisionManager来进行授权   46.         this.accessDecisionManager.decide(authenticated, object, attr);   47.      catch (AccessDeniedException accessDeniedException)    48.         /授权不成功向外发布事件   49.         AuthorizationFailureEvent event = new AuthorizationFailureEvent(object, attr, authenticated,   50.                 accessDeniedException);   51.         publishEvent(event);   52.         throw accessDeniedException;   53.     if (logger.isDebugEnabled()    54.         logger.debug("Authorization successful");   55.     AuthorizedEvent event = new AuthorizedEvent(object, attr, authenticated);   56.     publishEvent(event);   57.     / 这里构建一个RunAsManager来替代当前的Authentication对象,默认情况下使用的是NullRunAsManager会把SecurityContextHolder中的Authentication对象清空   58.     Authentication runAs = this.runAsManager.buildRunAs(authenticated, object, attr);   59.     if (runAs = null)    60.         if (logger.isDebugEnabled()    61.             logger.debug("RunAsManager did not change Authentication object");   62.         / no further work post-invocation   63.         return new InterceptorStatusToken(authenticated, false, attr, object);   64.      else    65.         if (logger.isDebugEnabled()    66.             logger.debug("Switching to RunAs Authentication: " + runAs.toString();   67.         SecurityContextHolder.getContext().setAuthentication(runAs);   68.         / revert to token.Authenticated post-invocation   69.         return new InterceptorStatusToken(authenticated, true, attr, object);    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对象,一般在登录时会放到SecurityContextHolder中去 if (SecurityContextHolder.getContext().getAuthentication() = null) credentialsNotFound(messages.getMessage("AbstractSecurityInterceptor.authenticationNotFound", "An Authentication object was not found in the SecurityContext"), object, attr); / 如果前面没有处理鉴权,这里需要对鉴权进行处理 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 that if (logger.isDebugEnabled() logger.debug("Successfully Authenticated: " + authenticated.toString(); /这里把鉴权成功后得到的Authentication保存到SecurityContextHolder中供下次使用 SecurityContextHolder.getContext().setAuthentication(authenticated); else /这里处理前面已经通过鉴权的请求,先从SecurityContextHolder中去取得Authentication authenticated = SecurityContextHolder.getContext().getAuthentication(); if (logger.isDebugEnabled() logger.debug("Previously Authenticated: " + authenticated.toString(); / 这是处理授权的过程 try /调用配置好的AccessDecisionManager来进行授权 this.accessDecisionManager.decide(authenticated, object, attr); catch (AccessDeniedException accessDeniedException) /授权不成功向外发布事件 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); / 这里构建一个RunAsManager来替代当前的Authentication对象,默认情况下使用的是NullRunAsManager会把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-invocation return 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-invocation return new InterceptorStatusToken(authenticated, true, attr, object);到这里我们假设配置AffirmativeBased作为AccessDecisionManager: Java代码 1. /这里定义了决策机制,需要全票才能通过   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.         /依次使用各个投票器进行投票,并对投票结果进行计票   8.         while (iter.hasNext()    9.             AccessDecisionVoter voter = (AccessDecisionVoter) iter.next();   10.             int result = voter.vote(authentication, object, config);   11.             /这是对投票结果进行处理,如果遇到其中一票通过,那就授权通过,如果是弃权或者反对,那就继续投票   12.             switch (result)    13.             case AccessDecisionVoter.ACCESS_GRANTED:   14.                 return;   15.             case AccessDecisionVoter.ACCESS_DENIED:   16.             /这里对反对票进行计数   17.                 deny+;   18.                 break;   19.             default:   20.                 break;   21.         /如果有反对票,抛出异常,整个授权不通过   22.         if (deny > 0)    23.             throw new AccessDeniedException(messages.getMessage("AbstractAccessDecisionManager.accessDenied",   24.                     "Access is denied");   25.         / 这里对弃权票进行处理,看看是全是弃权票的决定情况,默认是不通过,由allowIfAllAbstainDecisions变量控制   26.         checkAllowIfAllAbstainDecisions();   27. 具体的投票由投票器进行,我们这里配置了RoleVoter来进行投票:   28.     public int vote(Authentication authentication, Object object, ConfigAttributeDefinition config)    29.         int result = ACCESS_ABSTAIN;   30.         /这里取得资源的安全配置   31.         Iterator iter = config.getConfigAttributes();   32.         while (iter.hasNext()    33.             ConfigAttribute attribute = (ConfigAttribute) iter.next();   34.             if (this.supports(attribute)    35.                 result = ACCESS_DENIED;   36.                 / 这里对资源配置的安全授权级别进行判断,也就是匹配ROLE为前缀的角色配置   37.                 / 遍历每个配置属性,如果其中一个匹配该主体持有的GrantedAuthority,则访问被允许。   38.                 for (int i = 0; i < authentication.getAuthorities().length; i+)    39.                     if (attribute.getAttribute().equals(authentication.getAuthorities()i.getAuthority()    40.                         return ACCESS_GRANTED;   41.         return result;   /这里定义了决策机制,需要全票才能通过 public void decide(Authentication authentication, Object object, ConfigAttributeDefinition config) throws AccessDeniedException /这里取得配置好的迭代器集合 Iterator iter = this.getDecisionVoters().iterator(); int deny = 0; /依次使用各个投票器进行投票,并对投票结果进行计票 while (iter.hasNext() AccessDecisionVoter voter = (AccessDecisionVoter) iter.next(); int result = vo

    注意事项

    本文(Spring源代码解析(十):Spring Acegi框架授权的实现.doc)为本站会员(1595****071)主动上传,淘文阁 - 分享文档赚钱的网站仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知淘文阁 - 分享文档赚钱的网站(点击联系客服),我们立即给予删除!

    温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




    关于淘文阁 - 版权申诉 - 用户使用规则 - 积分规则 - 联系我们

    本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知淘文阁网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

    工信部备案号:黑ICP备15003705号 © 2020-2023 www.taowenge.com 淘文阁 

    收起
    展开