【asp源码栏目提醒】:网学会员,鉴于大家对asp源码十分关注,论文会员在此为大家搜集整理了“Acegi 源码解释-asp net学习网 - 讲义教程”一文,供大家参考学习!
c.net编程
学习网 Acegi
源码解释 Acegi
源码解释 内容 Acegi
源码解释 Acegi个人任务有三部分比较重要也是经常需要扩展的地方现都它们及其相关简要介绍如下它们分别是认证管理器暂时未写出、访问控制管理器主要授权、异常捕获Fitler用于验证不成功是跳转。
1、securityContextHolde.java 此类为框架级别的它里有很多的静态变量包括SecurityContext。
但SecurityContext默认使用的是ThreadLacal进行控制的。
它其中有三种控件SecurityContext方式 public static final String MODE_THREADLOCAL MODE_THREADLOCAL public static final String MODE_INHERITABLETHREADLOCAL MODE_INHERITABLETHREADLOCAL public static final String MODE_GLOBAL MODE_GLOBAL public static final String SYSTEM_PROPERTY acegi.security.strategy private static String strategyName System.getPropertySYSTEM_PROPERTY private static SecurityContextHolderStrategy strategy 通过静态代码块自动执行initialize方法 static initialize initialize方法通过startegyName确定采用哪种方式 SecurityContextHolder.MODE_THREADLOCALSecurityContext绑定到主线程这是默认的模式 SecurityContextHolder.MODE_GLOBALSecurityContext绑定到JVM中所有线程都使用同一个SecurityContext SecurityContextHolder.MODE_INHERITABLETHREADLOCALSecurityContext绑定到主线程及由主线程衍生的线程中。
private static void initialize if strategyName null .equalsstrategyName // Set default strategyName MODE_THREADLOCAL if strategyName.equalsMODE_THREADLOCAL strategy new ThreadLocalSecurityContextHolderStrategy else if strategyName.equalsMODE_INHERITABLETHREADLOCAL strategy new InheritableThreadLocalSecurityContextHolderStrategy else if strategyName.equalsMODE_GLOBAL strategy new GlobalSecurityContextHolderStrategy else // Try to load a custom strategy try Class clazz Class.forNamestrategyName Constructor customStrategy clazz.getConstructornew Class strategy SecurityContextHolderStrategy customStrategy.newInstancenew Object catch Exception ex ReflectionUtils.handleReflectionExceptionex initializeCount 在使用时可以通过调用 public static void setStrategyNameString strategyName SecurityContextHolder.strategyName strategyName initialize 来改变securityContextHolde中securityContex采用的方式。
2、FilterChainProxy.Java 将Acegi所需要在安全控制的所需要的执行全部配置在这里如下列配置 CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON PATTERN_TYPE_APACHE_ANT //.jpgNONE //.gifNONE //.pngNONE //.cssNONE //.jsNONE //.icoNONE //.curNONE /httpSessionContextIntegrationFilterauthenticationProcessingFiltercknowledgeProcessingFiltersecurityContextHolderAwareRequestFilteranonymousProcessingFilterlogoutFiltercDeskToplogoutFilterexceptionTranslationFilterfilterInvocationInterceptor 关键是将很多属性注入filterInvocationDefinitionSource对象中查看
源码可知filterInvocationDefinitionSource对象是FilterInvocationDefinitionSource类型其实在JDK中可以定义自己的编辑器类有关编辑器详细可见http://uule.iteye.com/blog/869060同时在JDK中如果没有明确指定编辑器类时
Java会自己查找类名EditorSupport 的类作为该类的编辑器类如在Acegi类中则使用了FilterInvocationDefinitionSourceEditorSupport编辑器类对Xml配置文件中的字符串进行相应的转换生成相应的Filter对象再放入FilterChainProxy中的Filter数组中然后再依次按顺序调用数组中的Filter上述代码中的httpSessionContextIntegrationFilter、authenticationProcessingFilter……等对象的Filter。
它的比对规则为 1、将整个Value的字符串传入 2、判断字符串中是否含有 PATTERN_TYPE_APACHE_ANT如果含有则指定资源匹配规则为按Ant Path 风格的匹配方式进行自动生成匹配PathBasedFilterInvocationDefinitionMap类对象传入默认一般采用这种方式。
如果不指定时则RegExpBasedFilterInvocationDefinitionMap采用的是Perl5风格的匹配方式。
生成的匹配对象都传入FilterInvocationDefinitionDecorator对象FilterInvocationDefinitionDecorator为FilterInvocationDefinitionSource接口的一个实现。
3、再比较是否含有DIRECTIVE_CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON字符串如果有则设置所有的匹配都转换成小写。
4、再按整个字符串按行读取//开头的不作处理表示注释 5、如果不是前面几个字符串且间含有号时号前半部分作为Ke后半部分作为Value最后全部存入FilterInvocationDefinitionDecorator类的对象中用于返回。
6、这样在FilterChainProxy就能取得filterInvocationDefinitionSource对象了并且可以根据对象中的数组每组的 //.pngNONE之类及每个数组元素中对应的Filter放入Filter数组中NONE表求不匹配。
在这个数据中找括号左边一个进行匹配满足后就执行右边的逻辑找到一个满足的后就不再往下查找就按顺序执行右边的逻辑。
3、授权管理器 说到授权管理器不得不先介绍几个对象。
ConfigAttributeDefinition变长数据默认时为10JDK里面的默认值用于储存用户组 FilterInvocation保存request response chain下一个Filter InterceptorStatusToken用来保存authentication、attrConfigAttributeDefinition对象资源对应用户、secureObjectFilterInvocation对象 投票器 RoleVoter将资源对应的角色组与本用户的角色组进行匹配找到则返回1没找到返回-1 AuthenticatedVoter将资源对应的角色组与FULLY、ANONYMOUSLY、REMEMBERED进行匹配如果找到则返回1没找到返回-1 表决器表决器中添加任意个相应的投票器 AffirmativeBased通过调用上面之类的Voter如果有一个Voter返回的结果为1则返回如果没有一个返回1则抛出异常 ConsensusBased通过对调用上面之类的Voter如果 返回1的比返回-1的多将返回否则抛出异常 UnanimousBased通过对调用上面之类的Voter如果有一个返回-1则抛出异常 如果上面几个都没返回最后根据allowIfAllAbstainDecisions属性如果设置为false上面执行即没有抛出异常又没返回将在最后时根据此属性抛出异常为Ture时不抛出默认为false. 授权管理器 AbstractSecurityInterceptor为
AspectJSecurityInterceptor、FilterSecurityInterceptor、MethodSecurityInterceptor的父类 可注入对象 eventPublisherApplicationEventPublisher类型用于监听 afterInvocationManagerAfterInvocationManager类型 accessDecisionManagerAccessDecisionManager类型 authenticationManagerAuthenticationManager类型 具体各种授权管理器实现 FilterSecurityInterceptor 在dofilter 中保存request response chain下一个Filter放入InterceptorStatusToken对象中执行invoke方法 1、Invoke在执行下一个Filter之前执行父类的beforeInvocation方法 2、beforeInvocation首先调用配置的objectDefinitionSource对象中的getAttributes方法此处为FilterSeurityIntercptor方法扩展点它主要作用是取得当前资源对应的角色放入ConfigAttributeDefinition对象中。
然后再调用配置的accessDecisionManager 对象的decide方法accessDecisionManager主要有三种分别是AffirmativeBased、ConsensusBased、UnanimousBased三种表决方式进行表决如果没有抛出异常则表示表决通过。
此时可能根据配置对监听器发出消息。
最后将所有信息装入InterceptorStatusToken对象中返回invoke方法中去。
3、Invoke将FilterInvocation对象中的值取得执行下一个Filter分别将其中的request、response作为参数传入。
最后在后面的Filter链都执行完后再执行父类的afterInvocation方法 4、afterInvocation如果afterInvocationManager对象不为空则执行其decide方法。
4、异常捕获Filter 异常捕获Filter需要配制在拦截器之前因为在拦截器会根据用户拥有的角色权限和资源需要的角色权限进行匹配投票如果验证不通过在拦截器直接抛出异常而在它之前需要异常Filter进行异常捕获。
exceptionTranslationFilter:它是异常捕获Filter在dofilter中将Filter链中的下一个Filter放入Try代码块中当授权没有成功时则进入相应的Catch中catch主要分成三种一种是AuthenticationException异常一个是AccessDeniedException异常还能就是ServletException异常如果都不是这几种则不处理异常。
处理的异常都是调用 handleException方法 1、handleException此方法根据前面几种不同类型的异常生成不同参数调用sendStartAuthentication方法如果对于异常想要作自己的处理此处可以作为扩展点 2、sendStartAuthentication父类的此方法中将SecurityContextHolder中的本线程的Authentication设置为空后再调用配置注入的authenticationEntryPoint对象的commence方法。
3、commence此方法用于地址跳转方法可分成两部分前部分主要用于取得如域名、端口、协议等、再调用determineUrlToUseForThisRequest方法取得转跳页面最后拼接成URl进行重定向。
该Filter还应该配置一个accessDeniedHandler对象注入用于处理ServletException异常 如参考配置 ?? 2011 c.net编程学习网
xml地图