Spring_SecurityAPI解读.doc_第1页
Spring_SecurityAPI解读.doc_第2页
Spring_SecurityAPI解读.doc_第3页
Spring_SecurityAPI解读.doc_第4页
Spring_SecurityAPI解读.doc_第5页
已阅读5页,还剩13页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

用户相关的信息是通过org.springframework.security.core.userdetails.UserDetailsService接口来加载的。该接口的唯一方法是loadUserByUsername(String username),用来根据用户名加载相关的信息。这个方法的返回值是org.springframework.security.core.userdetails.UserDetails接口类型,其中包含了用户的信息,包括用户名、密码、权限。是否启用、是否锁定、是否过期等。其中最重要的是用户权限,由org.springframework.security.core.GrantedAuthority接口来表示。虽然Spring Security内部的设计和实现比较复杂,但是一般情况下,开发人员只需要使用它默认提供的实现就可以满足绝大多数情况的需求,而且只需要简单的配置声明即可。使用数据库加载用户信息的时候,所生成的实体类必须有一些基本的信息,这个是框架的约定,这个约定是通过定义UserDetails接口来实现的,也就是你要用我这个框架,那么你就必须给我提供这些信息。public interface UserDetailsextends SerializableProvides core user information. Implementations are not used directly by Spring Security for security purposes. They simply store user information which is later encapsulated into Authentication objects. This allows non-security related user information (such as email addresses, telephone numbers etc) to be stored in a convenient location. Concrete implementations must take particular care to ensure the non-null contract detailed for each method is enforced. See User for a reference implementation (which you might like to extend). Concrete implementations should be immutable (value object semantics, like a String). This is because the UserDetails will be stored in caches and as such multiple threads may use the same instance. public interface UserDetailsServiceDefines an interface for implementations that wish to provide data access services to the DaoAuthenticationProvider. The interface requires only one read-only method, which simplifies support of new data access strategies. 1、 声明使用数据库来保存用户信息 首先定义了一个使用Apache Derby数据库的数据源,Spring Security的org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl类使用该数据源来加载用户信息。最后配置认证管理器使用该UserDetailsService。3、public interface SecurityContextextends SerializableInterface defining the minimum security information associated with the current thread of execution. The security context is stored in a SecurityContextHolder. org.springframework.security.core.context.SecurityContext接口表示的是当前应用的安全上下文。通过此接口可以获取和设置当前的认证对象。public interface Authenticationextends Principal, SerializableRepresents an authentication request. An Authentication object is not considered authenticated until it is processed by an AuthenticationManager. Stored in a request SecurityContext. org.springframework.security.core.Authentication接口用来表示认证对象。通过认证对象的方法可以判断当前用户是否已经通过认证,以及获取当前认证用户的相关信息,包括用户名、密码和权限等。要使用此认证对象,首先需要获取到SecurityContext对象。通过org.springframework.security.core.context.SecurityContextHolder类提供的静态方法getContext()就可以获取。再通过SecurityContext对象的getAuthentication()就可以得到认证对象。通过认证对象的getPrincipal()方法就可以获得当前的认证主体,通常是UserDetails接口的实现。处理过程:典型的认证过程就是当用户输入了用户名和密码之后,UserDetailService通过用户名找到对应的UserDetails对象,接着比较密码是否匹配。如果不匹配,则返回出错信息;如果匹配的话,说明用户认证成功,就创建一个Authentication的对象,如org.springframework.security.authentication.UsernamePasswordAuthenticationToken类的对象。再通过SecurityContext的setAuthentication()方法来设置此认证对象。public class FilterSecurityInterceptorextends AbstractSecurityInterceptorimplements Filter, OrderedPerforms security handling of HTTP resources via a filter implementation.The ObjectDefinitionSource required by this security interceptor is of type FilterInvocationDefinitionSource.Refer to AbstractSecurityInterceptor for details on the workflow. 通过实现Filter接口来完成对HTTP资源的安全控制。FilterSecurityInterceptor要求有一个FilterInvocationDefinitionSource类型的ObjectDefinitonSource参数。 参考AbstractSecurityInterceptor获得更多的工作流程细节。FilterSecurityInterceptor从名字来看好像是一个拦截器,但是从上面可以看出它实现了Filter接口。所以这个伪Interceptor可以直接处理request请求,它里面有这样的方法:doFilterpublic void doFilter(ServletRequestrequest, ServletResponseresponse, FilterChainchain) throws IOException, ServletExceptionMethod that is actually called by the filter chain. Simply delegates to the invoke(FilterInvocation) method. public abstract class AbstractSecurityInterceptorextends Objectimplements InitializingBean, ApplicationEventPublisherAware, MessageSourceAwareAbstract class that implements security interception for secure objects. The AbstractSecurityInterceptor will ensure the proper startup configuration of the security interceptor. It will also implement the proper handling of secure object invocations, namely: 这一个实现对安全对象安全管理的抽象类。AbstractSecurityInterceptor将会保证安全拦截的正确启动配置。也会实现对安全对象调用的恰当管理,也就是:1. Obtain the Authentication object from the SecurityContextHolder.从SecurityContextHolder中获得Authentication对象。2. Determine if the request relates to a secured or public invocation by looking up the secure object request against the ObjectDefinitionSource.如果请求关系到一个安全的或者是公共的调用就通过去查找ObjectDefinitionSource确定是否一个安全的对象请求。3. For an invocation that is secured (there is a ConfigAttributeDefinition for the secure object invocation): a. If either the Authentication.isAuthenticated() returns false, or the alwaysReauthenticate is true, authenticate the request against the configured AuthenticationManager. When authenticated, replace the Authentication object on the SecurityContextHolder with the returned value.b. Authorize the request against the configured AccessDecisionManager.c. Perform any run-as replacement via the configured RunAsManager.d. Pass control back to the concrete subclass, which will actually proceed with executing the object. A InterceptorStatusToken is returned so that after the subclass has finished proceeding with execution of the object, its finally clause can ensure the AbstractSecurityInterceptor is re-called and tidies up correctly.e. The concrete subclass will re-call the AbstractSecurityInterceptor via the afterInvocation(InterceptorStatusToken, Object) method.f. If the RunAsManager replaced the Authentication object, return the SecurityContextHolder to the object that existed after the call to AuthenticationManager.g. If an AfterInvocationManager is defined, invoke the invocation manager and allow it to replace the object due to be returned to the caller.4. For an invocation that is public (there is no ConfigAttributeDefinition for the secure object invocation): a. As described above, the concrete subclass will be returned an InterceptorStatusToken which is subsequently re-presented to the AbstractSecurityInterceptor after the secure object has been executed. The AbstractSecurityInterceptor will take no further action when its afterInvocation(InterceptorStatusToken, Object) is called.5. Control again returns to the concrete subclass, along with the Object that should be returned to the caller. The subclass will then return that result or exception to the original caller.public interface ObjectDefinitionSourceImplemented by classes that store and can identify the ConfigAttributeDefinition that applies to a given secure object invocation. 被这些可以存储和识别适用于给出的安全对象调用的ConfigAttributeDefinition类实现。public class ConfigAttributeDefinitionextends Objectimplements SerializableHolds a group of ConfigAttributes that are associated with a given secure object target - effectively a Collection. Once created, the object is immutable. All the ConfigAttributeDefinitions associated with a given AbstractSecurityInterceptor are stored in an ObjectDefinitionSource. 拥有一组与给出的安全目标对象关联的ConfigAttributes-事实上是一个集合。也就是这个对象内容保存有装有配置属性的集合。一旦被创建,这个对象就是不变的。所有与AbstractSecurityInterceptor关联的ConfigAttributeDefinitons都存储在ObjectDefinitionSource中。 也就是操作ObjectDefinitionSource实际上是为了获取ConfigAttributeDefinitions。 FilterSecurityInterceptor该filter也是个重量级的filter,主要是个拦截器的作用。该filter需要配置一下属性:1、 authenticationManager 校验密码并获取角色信息2、 objectDefinitionSource3、 accessDecisionManager-AffirmativeBased【具备两个属性:allowIfAllAbstainDecisions,decisionVoters】而decisionVoters可以配置为: a:RoleVoter 根据ROLE_来确定是否通过 b:AuthenticatedVoterFilterSecurityInterceptor.doFilter中做了什么呢?首先将request,response,chain封装成FilterInvocation fi,然后执行一下: a:beforeInvocation b:fi.getChain().doFilter() c:afterInvocation三个方法A、 beforeInvocation(FilterInvocation)方法返回值是InterceptorStatusToken,这个方法都做了什么呢?以下说明了它的运行逻辑:1、 filterSecurityInterceptor中配置了objectDefinitionSource,调用其getAttributes(fi)方法,getAttribute(fi)方法中调用fi.getRequestUrl()得到URL,然后调用objectDefinitonSource.lookupAttribute(url)这个lookup方法就可以从数据库resource表中获取url对应的resource。2、 将1中查询出来的resource与url逐一比较,如果匹配,则获得相应GrantedAuthority即roles。3、 将2中GrantedAuthority逐一getAuthority后根据,分隔拼凑成字符串authStr,并且new ConfigAttributeEditor(),再调用ConfigAttributeEditor.setAsText(authStr)和ConfigAttributeEditor.getValue(),将value强制转化成ConfigAttributeDefinition返回。setAsText方面里面:new ConfigAttributeDefinition,再将authStr拆分成数组,逐一调用addConfigAttribute方法将SecurityConfig(auth) add 到ConfigAttributeDefiniton中,再setVlaue将ConfigAttributeDefinition设置为value。因此调用getValue的返回值可以强制转化为ConfigAttributeDefinition类。4、 通过SecurityContextHolder.getContext().getAuthentication()获取Authentication。此处根据配置及Authentication.isAuthenticated()判断可能会再次调用authenticationManager的authenticate方法。5、 调用accessDecisionManager.decide(authenticated,FilterInvocation,ConfigAttributeDefiniton),下面分析一下AffirmativeBased这个decisionManager是如何decide的?1、 对AffirmativeBased配置的每一个decisionVoter执行:调用voter.vote(Authention,obj,ConfigAttributeDefiniton)获取是通过还是denny还是弃权。2、 如果denny的数量0,则异常不通过,如果有一个通过则decide方法完成返回3、 如果AffirmativeBased有allowIfAllAbstainDecisions(“如果全部弃权则通过”)属性,如果false,则抛出异常 RoleVoter.vote方法:从ConfigAttributeDefinition获取每一个ConfigAttribute.getAttribute(),判断是否以”ROLE_”开头: 如果是,检查Authentication中有没有与之匹配的,有则返回通过无则返回denny 如不是,则返回弃权。 AuthenticateVoter.vote方法:从ConfigAttributeDefiniton获取每一个ConfigAttribute,调用getAttribute(),判断是否:IS_AUTHENTICATED_FULLY:是则满足以下情况返回通过: *.既不是RememberMeAuthentication也不是AnonymousAuthenticationToken的实例IS_AUTHENTICATED_REMEMBERED:是则满足以下任一情况返回通过: a*.Authentication是RememberMeAuthenticationToken的实例 b*.既不是RememberMeAuthentication也不是AnonymousAuthenticationToken的实例IS_AUTHENTICATED_ANONYMOUSLY:是则满足以下任一情况返回通过: a*.Authentication是AnonymousAuthenticationToken的实例 b*.既不是RememberMeAuthentication也不是AnonymousAuthenticationToken的实例 c*.Authentication是RememberMeAuthenticationToken的实例 以上3种情况的判断中,如果依然没有return通过,则只要有一个Attribute()与以上3个相同,则返回 denny,否则弃权.public interface FactoryBeanInterface to be implemented by objects used within a BeanFactory which are themselves factories. If a bean implements this interface, it is used as a factory for an object to expose, not directly as a bean instance that will be exposed itself. 对象实现这个接口用作一个作为自己工厂的BeanFactory。如果bean实现了这个接口,那么它作为一个对象工厂暴露,而不是直接作为一个bean实例暴露自己。NB: A bean that implements this interface cannot be used as a normal bean. A FactoryBean is defined in a bean style, but the object exposed for bean references (getObject() is always the object that it creates. 实现了这个接口的bean不能当成一个普通的bean使用。FactoryBean以bean的方式定义,但是真正暴露出来的bean是通过getObject返回的,这个bean也是它自己创建的。FactoryBeans can support singletons and prototypes, and can either create objects lazily on demand or eagerly on startup. The SmartFactoryBean interface allows for exposing more fine-grained behavioral metadata. This interface is heavily used within the framework itself, for example for the AOP ProxyFactoryBean or the JndiObjectFactoryBean. It can be used for application components as well; however, this is not common outside of infrastructure code. NOTE: FactoryBean objects participate in the containing BeanFactorys synchronization of bean creation. There is usually no need for internal synchronization other than for purposes of lazy initialization within the FactoryBean itself (or the like). public interface FilterInvocationDefinitionSourceextends ObjectDefinitionSourceMarker interface for ObjectDefinitionSource implementations that are designed to perform lookups keyed on FilterInvocations. 为ObjectDefinitionSource实现者提供的一个标记接口,设计它的目的是实现在FilterInvocations中查找key。public class DefaultFilterInvocationDefinitionSourceextends Objectimplements FilterInvocationDefinitionSourceDefault implementation of FilterInvocationDefinitionSource. FilterInvocationDefinitionSource的默认实现者。 Stores an ordered map of compiled URL paths to ConfigAttributeDefinitions and provides URL matching against the items stored in this map using the configured UrlMatcher. 保存一个存储编译的URL路径的有序map到ConfigAttributeDefinitions中,使用配置的UrlMatcher来比较URL和存储在这个map里面的元素。The order of registering the regular expressions using the addSecureUrl(String, ConfigAttributeDefinition) is very important. The system will identify the first matching regular expression for a given HTTP URL. It will not proceed to evaluate later regular expressions if a match has already been found. Accordingly, the most specific regular expressions should be registered first, with the most general regular expressions registered last. 用addSecureUrl(String,ConfigAttributeDefition)注册的表达式规则的顺序是非常重要的。系统会首先将第一个匹配规则和请求的HTTP URL进行比较。如果一个匹配已经发现那么不会再去分析下表达式规则。因此,最特殊的表达式规则应该首先被注册,最普通的表达式规则最后被注册。If URLs are registered for a particular HTTP method using addSecureUrl(String, String, ConfigAttributeDefinition), then the method-specific matches will take precedence over any URLs which are registered without an HTTP method. 如果URLS是用addSecureUrl方法通过一个特殊的HTTP 方法注册的,那么这个特殊的方法匹配优先于任何没用通过HTTP方法注册的URLS。DefaultFilterInvocationDefinitionSourcepublic DefaultFilterInvocationDefinitionSource(UrlMatcherurlMatcher, LinkedHashMaprequestMap)Builds the internal request map from the supplied map. The key elements should be of type RequestKey, which contains a URL path and an optional HTTP method (may be null). The path stored in the key will depend on the type of the supplied UrlMatcher. Parameters:urlMatcher - typically an ant or regular expression matcher.requestMap - order-preserving map of .public interface UrlMatcherStrategy for deciding whether configured path matches a submitted candidate URL. 判断配置的路径是否和提交的候选URL匹配的策略。public class ConfigAttributeEditorextends PropertyEditorSupportA property editor that can create a populated ConfigAttributeDefinition from a comma separated list of values. 一个可以用以逗号分隔的list中的值创建ConfigAttributeDefiniton对象的属性编辑器。Trims preceding and trailing spaces from presented command separated tokens, as this can be a source of hard-to-spot configuration issues for end users. public class RequestKeyextends ObjectAPI中没有对这个进行介绍,不过可以看出它就是一个普通的类,不过从它的构造方法中我们可以看出一点端倪:RequestKey(Stringurl) RequestKey(Stringurl, Stringmethod)从这可以看出实际上这是一个加工URL的类,将url构造成RequestKey类型的对象。匹配URL地址恐 怕很多同志都有一个误解,就是Spring Security中配置URL的时候,要么配置成一个特定的URL,比如/admin/index.jsp,要么配置为某个路径下所有的URL,比如 /admin/*。如果你真的这么认为的话,那就太小看Spring Security了,/*只是默认提供的AntUrlPathMatcher所支持功能的一部分而已,下面我们就来破除迷信,深入讨论一下匹配URL地 址这方面的功能。AntUrlPathMatcher我们默认使用的URL匹配器就是这个AntUrlPathMatcher,它来自于/项目,是一种简单易懂的路径匹配策略。它为我们提供了三种通配符。 通配符:?示例:/admin/g?t.jsp匹配任意一个字符,/admin/g?t.jsp可以匹配/admin/get.jsp和/admin/got.jsp或是/admin/gxt.do。不能匹配/admin/xxx.jsp。 通配符:*示例:/admin/*.jsp匹配任意多个字符,但不能跨越目录。/*/index.jsp可以匹配/admin/index.jsp和/user/index.jsp,但是不能匹配/index.jsp和/user/test/index.jsp。 通配符:*示例:/*/index.jsp可以匹配任意多个字符,可以跨越目录,可以匹配/index.jsp,/admin/index.jsp,/user/admin/index.jsp和/a/b/c/d/index.jsppublic abstract class StringUtilsextends ObjectMiscellaneous String utility methods. Mainly for internal use within the framework; consider Jakartas Commons Lang for a more comprehensive suite of String utilities. This class delivers some simple functionality that should really be provided by the core Java String and StringBuffer classes, such as the ability to replace(java.lang.String, java.lang.String, java.lang.String) all occurrences of a given substring in a target string. It also provides easy-to-use methods to convert between delimited strings, such as CSV strings, and collections and arrays. hasTextpublic static boolean hasText(Stringstr)Check whether the given String has actual text. More specifically, returns true if the string not null, its length is greater than 0, and it contains at least one non-whitespace character. StringUtils.hasText(null) = false StringUtils.hasText() = false StringUtils.hasText( ) = false StringUtils.hasText(12345) = true StringUtils.hasText( 12345 ) = true public class FilterInvocationextends ObjectHolds objects associated with a HTTP filter.持有一个关联HTTP过滤器的对象。Guarantees the request and response are instances of HttpServletRequest and HttpServletResponse, and that there are no null objects. 保证request和response分别是HttpServletRequest和HttpServletResponse的实例,并且两者都不为空。Required so that security system classes can obtain access to the filter environment, as well as the request and response. 这个类是必须的,通过它安全系统类可以进入过滤器环境,也就是request和response所在的环境。public class InterceptorStatusTokenextends ObjectInterceptor状态标记A return object received by AbstractSecurityInterceptor subclasses. This class reflects the status of the security interception, so that the final call to AbstractSecurityInterceptor.afterInvocation(InterceptorStatusToken, Object) can tidy up correctly. public class PublicInvocationEventextends AbstractAuthorizationEventEvent that is generated whenever a public secure object is invoked.产生被保护的安全对象何时被调用的事件。A public secure object is a s

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论