OMG,到底在寻找什么..................
(构造一个完美的J2EE系统所需要的完整知识体系)
posts - 198,  comments - 37,  trackbacks - 0

原帖地址:http://bulain.javaeye.com/blog/24000

学习acegi-security
这几天对acegi研究了一下,现对这几天的研究做个总结。

网上资料对于acegi在web上的应用非常多,所以特意不从web入手,而从一般的java方法入手。

acegi的基本原理就是利用拦截器,对请求进行拦截,在拦截前和拦截后做些安全验证,以达到安全目的。所谓安全,一般包括两个部分,一为认证(authentication),二为授权(authorization)。

1,拦截器体系
acegi中拦截器为分为三类:
(1)filter拦截器(FilterSecurityInterceptor),主要对web应用进行拦截,即利用servlet的filter进行拦截。
(2)method拦截器,分为spring的method拦截器(MethodSecurityInterceptor)和aspectj的method拦截器(AspectJSecurityInterceptor)。

代码
  1. public   abstract   class  AbstractSecurityInterceptor  implements  InitializingBean, ApplicationEventPublisherAware,   
  2.     MessageSourceAware {   
  3.      private  AccessDecisionManager accessDecisionManager;   
  4.      private  AfterInvocationManager afterInvocationManager;   
  5.      private  ApplicationEventPublisher eventPublisher;   
  6.      private  AuthenticationManager authenticationManager;   
  7.      protected  MessageSourceAccessor messages = AcegiMessageSource.getAccessor();   
  8.      private  RunAsManager runAsManager =  new  NullRunAsManager();   
  9.      private   boolean  alwaysReauthenticate =  false ;   
  10.      private   boolean  rejectPublicInvocations =  false ;   
  11.      private   boolean  validateConfigAttributes =  true ;   
  12.     .........   
  13.   
  14.      protected  Object afterInvocation(InterceptorStatusToken token, Object returnedObject) {   
  15.        ............   
  16.     SecurityContextHolder.getContext().setAuthentication(token.getAuthentication());   
  17.     ............   
  18.         if  (afterInvocationManager !=  null ) {   
  19.             returnedObject = afterInvocationManager.decide(token.getAuthentication(), token.getSecureObject(),token.getAttr(), returnedObject);   
  20.         }   
  21.        ............   
  22.     }   
  23.   
  24.      protected  InterceptorStatusToken beforeInvocation(Object object) {           
  25.       ............   
  26.          authenticated =  this .authenticationManager.authenticate(SecurityContextHolder.getContext().getAuthentication());   
  27.       ............   
  28.           this .accessDecisionManager.decide(authenticated, object, attr);   
  29.          ............   
  30.          Authentication runAs =  this .runAsManager.buildRunAs(authenticated, object, attr);   
  31.           if  (runAs ==  null ) {   
  32.         ............   
  33.                return   new  InterceptorStatusToken(authenticated,  false , attr, object);    
  34.          }  else  {   
  35.         ............   
  36.               SecurityContextHolder.getContext().setAuthentication(runAs);   
  37.                return   new  InterceptorStatusToken(authenticated,  true , attr, object);    
  38.          }   
  39.       ............   
  40.     }   
  41. }   
  42.   
  43. public   class  FilterSecurityInterceptor  extends  AbstractSecurityInterceptor  implements  Filter {   
  44.       public   void  invoke(FilterInvocation fi)  throws  IOException, ServletException {   
  45.          if  ((fi.getRequest() !=  null ) && (fi.getRequest().getAttribute(FILTER_APPLIED) !=  null )   
  46.             && observeOncePerRequest) {   
  47.               
  48.             fi.getChain().doFilter(fi.getRequest(), fi.getResponse());   
  49.         }  else  {   
  50.               
  51.              if  (fi.getRequest() !=  null ) {   
  52.                 fi.getRequest().setAttribute(FILTER_APPLIED, Boolean.TRUE);   
  53.             }   
  54.   
  55.             InterceptorStatusToken token =  super .beforeInvocation(fi);   
  56.   
  57.              try  {   
  58.                 fi.getChain().doFilter(fi.getRequest(), fi.getResponse());   
  59.             }  finally  {   
  60.                  super .afterInvocation(token,  null );   
  61.             }   
  62.         }   
  63.     }   
  64.     ............   
  65. }   
  66.   
  67. public   class  MethodSecurityInterceptor  extends  AbstractSecurityInterceptor  implements  MethodInterceptor {       
  68.      public  Object invoke(MethodInvocation mi)  throws  Throwable {   
  69.         Object result =  null ;   
  70.         InterceptorStatusToken token =  super .beforeInvocation(mi);   
  71.   
  72.          try  {   
  73.             result = mi.proceed();   
  74.         }  finally  {   
  75.             result =  super .afterInvocation(token, result);   
  76.         }   
  77.   
  78.          return  result;   
  79.     }   
  80.     ............   
  81. }   
  82.   
  83. public   class  AspectJSecurityInterceptor  extends  AbstractSecurityInterceptor {   
  84.       public  Object invoke(JoinPoint jp, AspectJCallback advisorProceed) {   
  85.         Object result =  null ;   
  86.         InterceptorStatusToken token =  super .beforeInvocation(jp);   
  87.   
  88.          try  {   
  89.             result = advisorProceed.proceedWithObject();   
  90.         }  finally  {   
  91.             result =  super .afterInvocation(token, result);   
  92.         }   
  93.   
  94.          return  result;   
  95.     }   
  96.     ............   
  97. }  

上面的代码片断已经显示,所有的真正参与验证的代码都在父类AbstractSecurityInterceptor.beforeInvocation()之中进行,而对于拦截器都只是做些委托罢了。这样可以把具体的验证代码同拦截器分开,也有利于扩展,用其他的aop技术或拦截器进行扩展,可以很轻松。

认证体系由AuthenticationManager负责,授权体系由AccessDecisionManager负责,RunAsManager 是作为用户身份转换的手段。AfterInvocationManager留下了一个接口,可以扩展默认的授权体系,可以做一些其他额外的工作。

在AbstractSecurityInterceptor.beforeInvocation()中,
首先进行认证,authenticated = this.authenticationManager.authenticate(SecurityContextHolder.getContext().getAuthentication());
其次进行授权,this.accessDecisionManager.decide(authenticated, object, attr);

AbstractSecurityInterceptor.afterInvocation()中,
做其他扩展,returnedObject = afterInvocationManager.decide(token.getAuthentication(), token.getSecureObject(),token.getAttr(), returnedObject);

2,认证体系
2.1认证管理器
认证体系的核心为AuthenticationManager,他的方法authenticate(Authentication authentication)负责所有的认证。在acegi中,由具体类ProviderManager来进行认证过程。

代码
  1. public   interface  AuthenticationManager {   
  2.      public  Authentication authenticate(Authentication authentication)   
  3.          throws  AuthenticationException;   
  4. }   
  5.   
  6. public   abstract   class  AbstractAuthenticationManager   
  7.      implements  AuthenticationManager{   
  8.      public   final  Authentication authenticate(Authentication authRequest)   
  9.          throws  AuthenticationException {   
  10.          try  {   
  11.             Authentication authResult = doAuthentication(authRequest);   
  12.             copyDetails(authRequest, authResult);   
  13.   
  14.              return  authResult;   
  15.         }  catch  (AuthenticationException e) {   
  16.             e.setAuthentication(authRequest);   
  17.              throw  e;   
  18.         }   
  19.     }   
  20.   
  21.      private   void  copyDetails(Authentication source, Authentication dest) {   
  22.          if  ((dest  instanceof  AbstractAuthenticationToken) && (dest.getDetails() ==  null )) {   
  23.             AbstractAuthenticationToken token = (AbstractAuthenticationToken) dest;   
  24.   
  25.             token.setDetails(source.getDetails());   
  26.         }   
  27.     }   
  28.   
  29.      protected   abstract  Authentication doAuthentication(Authentication authentication)   
  30.          throws  AuthenticationException;   
  31.   
  32.     .........   
  33. }   
  34.   
  35. public   class  ProviderManager  extends  AbstractAuthenticationManager  implements  InitializingBean,   
  36.     ApplicationEventPublisherAware, MessageSourceAware {   
  37.      private  List providers;   
  38.     ............   
  39.      public  Authentication doAuthentication(Authentication authentication)   
  40.          throws  AuthenticationException {   
  41.      .........   
  42.         Iterator iter = providers.iterator();   
  43.         ............   
  44.          while  (iter.hasNext()) {   
  45.             .............   
  46.             AuthenticationProvider provider = (AuthenticationProvider) iter.next();   
  47.             .........   
  48.             result = provider.authenticate(authentication);   
  49.             ............   
  50.         }   
  51.         ............   
  52.     }   
  53.     .........   
  54. }  

从上面代码片断可以看出,真正的认证过程是在ProviderManager.doAuthentication()中进行的。而ProviderManager并不是具体的认证者,他只是个管理器,它要将具体的认证过程委托给具体的认证器提供者AuthenticationProvider去做。

2.2认证提供者
认证提供者就有很多了,可以提供各种各样的认证。如dao,ldap,anonymous,authbyadapter,cas,jaas,remeberme,remote,runnasimpl,testing,x509等。

代码
  1. public   interface  AuthenticationProvider {   
  2.      public  Authentication authenticate(Authentication authentication)  throws  AuthenticationException;   
  3.      public   boolean  supports(Class authentication);   
  4. }  

具体的认证提供者类就不详细分析了,只提个名字:DaoAuthenticationProvider,LdapAuthenticationProvider,AnonymousAuthenticationProvider,AuthByAdapterProvider,CasAuthenticationProvider,JaasAuthenticationProvider,RememberMeAuthenticationProvider,RemoteAuthenticationProvider,RunAsImplAuthenticationProvider,TestingAuthenticationProvider,X509AuthenticationProvider。

3,授权体系
3.1授权管理器
授权体系的核心为授权管理器(AccessDecisionManager),它的方法decide(Authentication authentication, Object object, ConfigAttributeDefinition config)进行具体的授权动作。

代码
  1. public   interface  AccessDecisionManager {   
  2.       
  3.      public   void  decide(Authentication authentication, Object object, ConfigAttributeDefinition config)   
  4.          throws  AccessDeniedException, InsufficientAuthenticationException;   
  5.      public   boolean  supports(ConfigAttribute attribute);   
  6.      public   boolean  supports(Class clazz);   
  7. }   
  8.   
  9. public   abstract   class  AbstractAccessDecisionManager  implements  AccessDecisionManager, InitializingBean,   
  10.     MessageSourceAware {   
  11.      private  List decisionVoters;   
  12.      protected  MessageSourceAccessor messages = AcegiMessageSource.getAccessor();   
  13.      private   boolean  allowIfAllAbstainDecisions =  false ;   
  14.   
  15.      public   boolean  supports(ConfigAttribute attribute) {   
  16.         Iterator iter =  this .decisionVoters.iterator();   
  17.   
  18.          while  (iter.hasNext()) {   
  19.             AccessDecisionVoter voter = (AccessDecisionVoter) iter.next();   
  20.   
  21.              if  (voter.supports(attribute)) {   
  22.                  return   true ;   
  23.             }   
  24.         }   
  25.   
  26.          return   false ;   
  27.     }   
  28.   
  29.      public   boolean  supports(Class clazz) {   
  30.         Iterator iter =  this .decisionVoters.iterator();   
  31.   
  32.          while  (iter.hasNext()) {   
  33.             AccessDecisionVoter voter = (AccessDecisionVoter) iter.next();   
  34.   
  35.              if  (!voter.supports(clazz)) {   
  36.                  return   false ;   
  37.             }   
  38.         }   
  39.   
  40.          return   true ;   
  41.     }   
  42.     ..............   
  43. }   
  44.   
  45. public   class  AffirmativeBased  extends  AbstractAccessDecisionManager {   
  46.      public   void  decide(Authentication authentication, Object object, ConfigAttributeDefinition config)   
  47.          throws  AccessDeniedException {   
  48.         Iterator iter =  this .getDecisionVoters().iterator();   
  49.          int  deny =  0 ;   
  50.   
  51.          while  (iter.hasNext()) {   
  52.             AccessDecisionVoter voter = (AccessDecisionVoter) iter.next();   
  53.              int  result = voter.vote(authentication, object, config);   
  54.   
  55.              switch  (result) {   
  56.              case  AccessDecisionVoter.ACCESS_GRANTED:   
  57.                  return ;   
  58.   
  59.              case  AccessDecisionVoter.ACCESS_DENIED:   
  60.                 deny++;   
  61.   
  62.                  break ;   
  63.   
  64.              default :   
  65.                  break ;   
  66.             }   
  67.         }   
  68.   
  69.          if  (deny >  0 ) {   
  70.              throw   new  AccessDeniedException(messages.getMessage( "AbstractAccessDecisionManager.accessDenied" ,   
  71.                      "Access is denied" ));   
  72.         }   
  73.   
  74.          // To get this far, every AccessDecisionVoter abstained   
  75.         checkAllowIfAllAbstainDecisions();   
  76.     }   
  77.     ..............   
  78. }   
  79.   
  80. public   class  ConsensusBased  extends  AbstractAccessDecisionManager {   
  81.      public   void  decide(Authentication authentication, Object object, ConfigAttributeDefinition config)   
  82.          throws  AccessDeniedException {   
  83.         Iterator iter =  this .getDecisionVoters().iterator();   
  84.          int  grant =  0 ;   
  85.          int  deny =  0 ;   
  86.          int  abstain =  0 ;   
  87.   
  88.          while  (iter.hasNext()) {   
  89.             AccessDecisionVoter voter = (AccessDecisionVoter) iter.next();   
  90.              int  result = voter.vote(authentication, object, config);   
  91.   
  92.              switch  (result) {   
  93.              case  AccessDecisionVoter.ACCESS_GRANTED:   
  94.                 grant++;   
  95.   
  96.                  break ;   
  97.   
  98.              case  AccessDecisionVoter.ACCESS_DENIED:   
  99.                 deny++;   
  100.   
  101.                  break ;   
  102.   
  103.              default :   
  104.                 abstain++;   
  105.   
  106.                  break ;   
  107.             }   
  108.         }   
  109.   
  110.          if  (grant > deny) {   
  111.              return ;   
  112.         }   
  113.   
  114.          if  (deny > grant) {   
  115.              throw   new  AccessDeniedException(messages.getMessage( "AbstractAccessDecisionManager.accessDenied" ,   
  116.                      "Access is denied" ));   
  117.         }   
  118.   
  119.          if  ((grant == deny) && (grant !=  0 )) {   
  120.              if  ( this .allowIfEqualGrantedDeniedDecisions) {   
  121.                  return ;   
  122.             }  else  {   
  123.                  throw   new  AccessDeniedException(messages.getMessage( "AbstractAccessDecisionManager.accessDenied" ,   
  124.                          "Access is denied" ));   
  125.             }   
  126.         }   
  127.   
  128.          // To get this far, every AccessDecisionVoter abstained   
  129.         checkAllowIfAllAbstainDecisions();   
  130.     }   
  131.     ..............   
  132. }   
  133.   
  134. public   class  UnanimousBased  extends  AbstractAccessDecisionManager {   
  135.      public   void  decide(Authentication authentication, Object object, ConfigAttributeDefinition config)   
  136.          throws  AccessDeniedException {   
  137.          int  grant =  0 ;   
  138.          int  abstain =  0 ;   
  139.   
  140.         Iterator configIter = config.getConfigAttributes();   
  141.   
  142.          while  (configIter.hasNext()) {   
  143.             ConfigAttributeDefinition thisDef =  new  ConfigAttributeDefinition();   
  144.             thisDef.addConfigAttribute((ConfigAttribute) configIter.next());   
  145.   
  146.             Iterator voters =  this .getDecisionVoters().iterator();   
  147.   
  148.              while  (voters.hasNext()) {   
  149.                 AccessDecisionVoter voter = (AccessDecisionVoter) voters.next();   
  150.                  int  result = voter.vote(authentication, object, thisDef);   
  151.   
  152.                  switch  (result) {   
  153.                  case  AccessDecisionVoter.ACCESS_GRANTED:   
  154.                     grant++;   
  155.   
  156.                      break ;   
  157.   
  158.                  case  AccessDecisionVoter.ACCESS_DENIED:   
  159.                      throw   new  AccessDeniedException(messages.getMessage( "AbstractAccessDecisionManager.accessDenied" ,   
  160.                              "Access is denied" ));   
  161.   
  162.                  default :   
  163.                     abstain++;   
  164.   
  165.                      break ;   
  166.                 }   
  167.             }   
  168.         }   
  169.   
  170.          // To get this far, there were no deny votes   
  171.          if  (grant >  0 ) {   
  172.              return ;   
  173.         }   
  174.   
  175.          // To get this far, every AccessDecisionVoter abstained   
  176.         checkAllowIfAllAbstainDecisions();   
  177.     }   
  178.     ..............   
  179. }  

授权管理器AccessDecisionManager默认有三个实现,具体为AffirmativeBased,ConsensusBased,UnanimousBased。三个具体实现都大同小异,主要在具有角色是否应该授权上。
而具体能否单个角色是否授权,是委派给AccessDecisionVoter去做的。

3.2授权投票者
授权投票责的核心是接口AccessDecisionVoter。他有几个具体实现类:BasicAclEntryVoter,AuthenticatedVoter,RoleVoter。

代码
  1. public   interface  AccessDecisionVoter {   
  2.       
  3.      public   static   final   int  ACCESS_GRANTED =  1 ;   
  4.      public   static   final   int  ACCESS_ABSTAIN =  0 ;   
  5.      public   static   final   int  ACCESS_DENIED = - 1 ;   
  6.   
  7.      public   boolean  supports(ConfigAttribute attribute);   
  8.      public   boolean  supports(Class clazz);   
  9.      public   int  vote(Authentication authentication, Object object, ConfigAttributeDefinition config);   
  10. }   
  11.   
  12. public   abstract   class  AbstractAclVoter  implements  AccessDecisionVoter {   
  13.      public   boolean  supports(Class clazz) {   
  14.          if  (MethodInvocation. class .isAssignableFrom(clazz)) {   
  15.              return   true ;   
  16.         }  else   if  (JoinPoint. class .isAssignableFrom(clazz)) {   
  17.              return   true ;   
  18.         }  else  {   
  19.              return   false ;   
  20.         }   
  21.     }   
  22.     ............   
  23. }   
  24.   
  25. public   class  BasicAclEntryVoter  extends  AbstractAclVoter  implements  InitializingBean {     
  26.      private  AclManager aclManager;   
  27.      private  String internalMethod;   
  28.      private  String processConfigAttribute;   
  29.      private   int [] requirePermission;   
  30.   
  31.      public   boolean  supports(ConfigAttribute attribute) {   
  32.          if  ((attribute.getAttribute() !=  null ) && attribute.getAttribute().startsWith(getProcessConfigAttribute())) {   
  33.              return   true ;   
  34.         }  else  {   
  35.              return   false ;   
  36.         }   
  37.     }   
  38.   
  39.      public   int  vote(Authentication authentication, Object object, ConfigAttributeDefinition config) {   
  40.         Iterator iter = config.getConfigAttributes();   
  41.   
  42.          while  (iter.hasNext()) {   
  43.             ConfigAttribute attr = (ConfigAttribute) iter.next();   
  44.   
  45.              if  ( this .supports(attr)) {   
  46.                  // Need to make an access decision on this invocation   
  47.                  // Attempt to locate the domain object instance to process   
  48.                 Object domainObject = getDomainObjectInstance(object);   
  49.   
  50.                  // If domain object is null, vote to abstain   
  51.                  if  (domainObject ==  null ) {   
  52.                      if  (logger.isDebugEnabled()) {   
  53.                         logger.debug( "Voting to abstain - domainObject is null" );   
  54.                     }   
  55.   
  56.                      return  AccessDecisionVoter.ACCESS_ABSTAIN;   
  57.                 }   
  58.   
  59.                  // Evaluate if we are required to use an inner domain object   
  60.                  if  ((internalMethod !=  null ) && ! "" .equals(internalMethod)) {   
  61.                      try  {   
  62.                         Class clazz = domainObject.getClass();   
  63.                         Method method = clazz.getMethod(internalMethod,  new  Class[] {});   
  64.                         domainObject = method.invoke(domainObject,  new  Object[] {});   
  65.                     }  catch  (NoSuchMethodException nsme) {   
  66.                          throw   new  AuthorizationServiceException( "Object of class '"  + domainObject.getClass()   
  67.                             +  "' does not provide the requested internalMethod: "  + internalMethod);   
  68.                     }  catch  (IllegalAccessException iae) {   
  69.                          if  (logger.isDebugEnabled()) {   
  70.                             logger.debug( "IllegalAccessException" , iae);   
  71.   
  72.                              if  (iae.getCause() !=  null ) {   
  73.                                 logger.debug( "Cause: "  + iae.getCause().getMessage(), iae.getCause());   
  74.                             }   
  75.                         }   
  76.   
  77.                          throw   new  AuthorizationServiceException( "Problem invoking internalMethod: "  + internalMethod   
  78.                             +  " for object: "  + domainObject);   
  79.                     }  catch  (InvocationTargetException ite) {   
  80.                          if  (logger.isDebugEnabled()) {   
  81.                             logger.debug( "InvocationTargetException" , ite);   
  82.   
  83.                              if  (ite.getCause() !=  null ) {   
  84.                                 logger.debug( "Cause: "  + ite.getCause().getMessage(), ite.getCause());   
  85.                             }   
  86.                         }   
  87.   
  88.                          throw   new  AuthorizationServiceException( "Problem invoking internalMethod: "  + internalMethod   
  89.                             +  " for object: "  + domainObject);   
  90.                     }   
  91.                 }   
  92.   
  93.                  // Obtain the ACLs applicable to the domain object   
  94.                 AclEntry[] acls = aclManager.getAcls(domainObject, authentication);   
  95.   
  96.                  // If principal has no permissions for domain object, deny   
  97.                  if  ((acls ==  null ) || (acls.length ==  0 )) {   
  98.                      if  (logger.isDebugEnabled()) {   
  99.                         logger.debug( "Voting to deny access - no ACLs returned for this principal" );   
  100.                     }   
  101.   
  102.                      return  AccessDecisionVoter.ACCESS_DENIED;   
  103.                 }   
  104.   
  105.                  // Principal has some permissions for domain object, check them   
  106.                  for  ( int  i =  0 ; i < acls.length; i++) {   
  107.                      // Locate processable AclEntrys   
  108.                      if  (acls[i]  instanceof  BasicAclEntry) {   
  109.                         BasicAclEntry processableAcl = (BasicAclEntry) acls[i];   
  110.   
  111.                          // See if principal has any of the required permissions   
  112.                          for  ( int  y =  0 ; y < requirePermission.length; y++) {   
  113.                              if  (processableAcl.isPermitted(requirePermission[y])) {   
  114.                                  if  (logger.isDebugEnabled()) {   
  115.                                     logger.debug( "Voting to grant access" );   
  116.                                 }   
  117.   
  118.                                  return  AccessDecisionVoter.ACCESS_GRANTED;   
  119.                             }   
  120.                         }   
  121.                     }   
  122.                 }   
  123.   
  124.                  // No permissions match   
  125.                  if  (logger.isDebugEnabled()) {   
  126.                     logger.debug(   
  127.                          "Voting to deny access - ACLs returned, but insufficient permissions for this principal" );   
  128.                 }   
  129.   
  130.                  return  AccessDecisionVoter.ACCESS_DENIED;   
  131.             }   
  132.         }   
  133.   
  134.          return  AccessDecisionVoter.ACCESS_ABSTAIN;   
  135.     }   
  136.     ...............   
  137. }   
  138.   
  139. public   class  AuthenticatedVoter  implements  AccessDecisionVoter {   
  140.   
  141.      public   static   final  String IS_AUTHENTICATED_FULLY =  "IS_AUTHENTICATED_FULLY" ;   
  142.      public   static   final  String IS_AUTHENTICATED_REMEMBERED =  "IS_AUTHENTICATED_REMEMBERED" ;   
  143.      public   static   final  String IS_AUTHENTICATED_ANONYMOUSLY =  "IS_AUTHENTICATED_ANONYMOUSLY" ;   
  144.   
  145.      private  AuthenticationTrustResolver authenticationTrustResolver =  new  AuthenticationTrustResolverImpl();   
  146.   
  147.      private   boolean  isFullyAuthenticated(Authentication authentication) {   
  148.          return  (!authenticationTrustResolver.isAnonymous(authentication)   
  149.         && !authenticationTrustResolver.isRememberMe(authentication));   
  150.     }   
  151.   
  152.      public   void  setAuthenticationTrustResolver(AuthenticationTrustResolver authenticationTrustResolver) {   
  153.         Assert.notNull(authenticationTrustResolver,  "AuthenticationTrustResolver cannot be set to null" );   
  154.          this .authenticationTrustResolver = authenticationTrustResolver;   
  155.     }   
  156.   
  157.      public   boolean  supports(ConfigAttribute attribute) {   
  158.          if  ((attribute.getAttribute() !=  null )   
  159.             && (IS_AUTHENTICATED_FULLY.equals(attribute.getAttribute())   
  160.             || IS_AUTHENTICATED_REMEMBERED.equals(attribute.getAttribute())   
  161.             || IS_AUTHENTICATED_ANONYMOUSLY.equals(attribute.getAttribute()))) {   
  162.              return   true ;   
  163.         }  else  {   
  164.              return   false ;   
  165.         }   
  166.     }   
  167.   
  168.      public   boolean  supports(Class clazz) {   
  169.          return   true ;   
  170.     }   
  171.   
  172.      public   int  vote(Authentication authentication, Object object, ConfigAttributeDefinition config) {   
  173.          int  result = ACCESS_ABSTAIN;   
  174.         Iterator iter = config.getConfigAttributes();   
  175.   
  176.          while  (iter.hasNext()) {   
  177.             ConfigAttribute attribute = (ConfigAttribute) iter.next();   
  178.   
  179.              if  ( this .supports(attribute)) {   
  180.                 result = ACCESS_DENIED;   
  181.   
  182.                  if  (IS_AUTHENTICATED_FULLY.equals(attribute.getAttribute())) {   
  183.                      if  (isFullyAuthenticated(authentication)) {   
  184.                          return  ACCESS_GRANTED;   
  185.                     }   
  186.                 }   
  187.   
  188.                  if  (IS_AUTHENTICATED_REMEMBERED.equals(attribute.getAttribute())) {   
  189.                      if  (authenticationTrustResolver.isRememberMe(authentication)   
  190.                         || isFullyAuthenticated(authentication)) {   
  191.                          return  ACCESS_GRANTED;   
  192.                     }   
  193.                 }   
  194.   
  195.                  if  (IS_AUTHENTICATED_ANONYMOUSLY.equals(attribute.getAttribute())) {   
  196.                      if  (authenticationTrustResolver.isAnonymous(authentication) || isFullyAuthenticated(authentication)   
  197.                         || authenticationTrustResolver.isRememberMe(authentication)) {   
  198.                          return  ACCESS_GRANTED;   
  199.                     }   
  200.                 }   
  201.             }   
  202.         }   
  203.   
  204.          return  result;   
  205.     }   
  206. }   
  207.   
  208. public   class  RoleVoter  implements  AccessDecisionVoter {   
  209.      private  String rolePrefix =  "ROLE_" ;   
  210.   
  211.      public   boolean  supports(ConfigAttribute attribute) {   
  212.          if  ((attribute.getAttribute() !=  null ) && attribute.getAttribute().startsWith(getRolePrefix())) {   
  213.              return   true ;   
  214.         }  else  {   
  215.              return   false ;   
  216.         }   
  217.     }   
  218.   
  219.      public   boolean  supports(Class clazz) {   
  220.          return   true ;   
  221.     }   
  222.   
  223.      public   int  vote(Authentication authentication, Object object, ConfigAttributeDefinition config) {   
  224.          int  result = ACCESS_ABSTAIN;   
  225.         Iterator iter = config.getConfigAttributes();   
  226.   
  227.          while  (iter.hasNext()) {   
  228.             ConfigAttribute attribute = (ConfigAttribute) iter.next();   
  229.   
  230.              if  ( this .supports(attribute)) {   
  231.                 result = ACCESS_DENIED;   
  232.   
  233.                  for  ( int  i =  0 ; i < authentication.getAuthorities().length; i++) {   
  234.                      if  (attribute.getAttribute().equals(authentication.getAuthorities()[i].getAuthority())) {   
  235.                          return  ACCESS_GRANTED;   
  236.                     }   
  237.                 }   
  238.             }   
  239.         }   
  240.          return  result;   
  241.     }   
  242. }  

这三个授权投票实现类中 acl 又最复杂。他会委托给acl管理器(AclManager)来做具体的授权工作。

3.3acl授权体系
AclManager只有一个实现类AclProviderManager ,负责提供acl授权实体。

代码
  1. public   interface  AclManager {   
  2.       
  3.      public  AclEntry[] getAcls(Object domainInstance);   
  4.      public  AclEntry[] getAcls(Object domainInstance, Authentication authentication);   
  5. }   
  6.   
  7. public   class  AclProviderManager  implements  AclManager, InitializingBean {     
  8.      public  AclEntry[] getAcls(Object domainInstance) {   
  9.         Assert.notNull(domainInstance,  "domainInstance is null - violating interface contract" );   
  10.   
  11.         Iterator iter = providers.iterator();   
  12.   
  13.          while  (iter.hasNext()) {   
  14.             AclProvider provider = (AclProvider) iter.next();   
  15.   
  16.              if  (provider.supports(domainInstance)) {   
  17.                  if  (logger.isDebugEnabled()) {   
  18.                     logger.debug( "ACL lookup using "  + provider.getClass().getName());   
  19.                 }   
  20.   
  21.                  return  provider.getAcls(domainInstance);   
  22.             }   
  23.         }   
  24.   
  25.          if  (logger.isDebugEnabled()) {   
  26.             logger.debug( "No AclProvider found for "  + domainInstance.toString());   
  27.         }   
  28.   
  29.          return   null ;   
  30.     }   
  31.   
  32.      public  AclEntry[] getAcls(Object domainInstance, Authentication authentication) {   
  33.         Assert.notNull(domainInstance,  "domainInstance is null - violating interface contract" );   
  34.         Assert.notNull(authentication,  "authentication is null - violating interface contract" );   
  35.   
  36.         Iterator iter = providers.iterator();   
  37.   
  38.          while  (iter.hasNext()) {   
  39.             AclProvider provider = (AclProvider) iter.next();   
  40.   
  41.              if  (provider.supports(domainInstance)) {   
  42.                  if  (logger.isDebugEnabled()) {   
  43.                     logger.debug( "ACL lookup using "  + provider.getClass().getName());   
  44.                 }   
  45.   
  46.                  return  provider.getAcls(domainInstance, authentication);   
  47.             }  else  {   
  48.                  if  (logger.isDebugEnabled()) {   
  49.                     logger.debug( "Provider "  + provider.toString() +  " does not support "  + domainInstance);   
  50.                 }   
  51.             }   
  52.         }   
  53.   
  54.          if  (logger.isDebugEnabled()) {   
  55.             logger.debug( "No AclProvider found for "  + domainInstance.toString());   
  56.         }   
  57.   
  58.          return   null ;   
  59.     }   
  60.     .........   
  61. }  
posted on 2006-12-28 23:52 OMG 阅读(1312) 评论(0)  编辑  收藏 所属分类: Auth/acegi

只有注册用户登录后才能发表评论。


网站导航:
 

<2006年12月>
262728293012
3456789
10111213141516
17181920212223
24252627282930
31123456

常用链接

留言簿(1)

随笔分类

随笔档案

IT风云人物

文档

朋友

相册

经典网站

搜索

  •  

最新评论

阅读排行榜

评论排行榜