SpringSecurity API解读.docx
- 文档编号:2742386
- 上传时间:2023-05-04
- 格式:DOCX
- 页数:20
- 大小:28.22KB
SpringSecurity API解读.docx
《SpringSecurity API解读.docx》由会员分享,可在线阅读,更多相关《SpringSecurity API解读.docx(20页珍藏版)》请在冰点文库上搜索。
SpringSecurityAPI解读
用户相关的信息是通过org.springframework.security.core.userdetails.UserDetailsService接
口来加载的。
该接口的唯一方法是loadUserByUsername(Stringusername),用来根据用户名加载相关的信息。
这个方法的返回值是org.springframework.security.core.userdetails.UserDetails接口类型,其中包含了用户的信息,包括用户名、密码、权限。
是否启用、是否锁定、是否过期等。
其中最重要的是用户权限,由org.springframework.security.core.GrantedAuthority接口来表示。
虽然SpringSecurity内部的设计和实现比较复杂,但是一般情况下,开发人员只需要使用它默认提供的实现就可以满足绝大多数情况的需求,而且只需要简单的配置声明即可。
使用数据库加载用户信息的时候,所生成的实体类必须有一些基本的信息,这个是框架的约定,这个约定是通过定义UserDetails接口来实现的,也就是你要用我这个框架,那么你就必须给我提供这些信息。
publicinterfaceUserDetails
extendsSerializable
Providescoreuserinformation.
ImplementationsarenotuseddirectlybySpringSecurityforsecuritypurposes.TheysimplystoreuserinformationwhichislaterencapsulatedintoAuthenticationobjects.Thisallowsnon-securityrelateduserinformation(suchasemailaddresses,telephonenumbersetc)tobestoredinaconvenientlocation.
Concreteimplementationsmusttakeparticularcaretoensurethenon-nullcontractdetailedforeachmethodisenforced.SeeUserforareferenceimplementation(whichyoumightliketoextend).
Concreteimplementationsshouldbeimmutable(valueobjectsemantics,likeaString).ThisisbecausetheUserDetailswillbestoredincachesandassuchmultiplethreadsmayusethesameinstance.
publicinterfaceUserDetailsService
DefinesaninterfaceforimplementationsthatwishtoprovidedataaccessservicestotheDaoAuthenticationProvider.
Theinterfacerequiresonlyoneread-onlymethod,whichsimplifiessupportofnewdataaccessstrategies.
1、声明使用数据库来保存用户信息
class="org.springframework.jdbc.datasource.DriverManagerDataSource"> derby: //localhost: 1527/mycompany"/> class="org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl"> authentication-manager> authentication-provideruser-service-ref="userDetailsService"/> authentication-manager> 首先定义了一个使用ApacheDerby数据库的数据源,SpringSecurity的org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl类使用该数据源来加载用户信息。 最后配置认证管理器使用该UserDetailsService。 3、publicinterfaceSecurityContext extendsSerializable Interfacedefiningtheminimumsecurityinformationassociatedwiththecurrentthreadofexecution. ThesecuritycontextisstoredinaSecurityContextHolder. org.springframework.security.core.context.SecurityContext接口表示的是当前应用的安全上下文。 通过此接口可以获取和设置当前的认证对象。 publicinterfaceAuthentication extendsPrincipal,Serializable Representsanauthenticationrequest. AnAuthenticationobjectisnotconsideredauthenticateduntilitisprocessedbyanAuthenticationManager. StoredinarequestSecurityContext. 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()方法来设置此认证对象。 publicclassFilterSecurityInterceptor extendsAbstractSecurityInterceptor implementsFilter,Ordered PerformssecurityhandlingofHTTPresourcesviaafilterimplementation. TheObjectDefinitionSourcerequiredbythissecurityinterceptorisoftypeFilterInvocationDefinitionSource. RefertoAbstractSecurityInterceptorfordetailsontheworkflow. 通过实现Filter接口来完成对HTTP资源的安全控制。 FilterSecurityInterceptor要求有一个FilterInvocationDefinitionSource类型的ObjectDefinitonSource参数。 参考AbstractSecurityInterceptor获得更多的工作流程细节。 FilterSecurityInterceptor从名字来看好像是一个拦截器,但是从上面可以看出它实现了Filter接口。 所以这个伪Interceptor可以直接处理request请求,它里面有这样的方法: doFilter publicvoiddoFilter(ServletRequest request, ServletResponse response, FilterChain chain) throwsIOException, ServletException Methodthatisactuallycalledbythefilterchain.Simplydelegatestotheinvoke(FilterInvocation)method. publicabstractclassAbstractSecurityInterceptor extendsObject implementsInitializingBean,ApplicationEventPublisherAware,MessageSourceAware Abstractclassthatimplementssecurityinterceptionforsecureobjects. TheAbstractSecurityInterceptorwillensuretheproperstartupconfigurationofthesecurityinterceptor.Itwillalsoimplementtheproperhandlingofsecureobjectinvocations,namely: 这一个实现对安全对象安全管理的抽象类。 AbstractSecurityInterceptor将会保证安全拦截的正确启动配置。 也会实现对安全对象调用的恰当管理,也就是: 1.ObtaintheAuthenticationobjectfromtheSecurityContextHolder. 从SecurityContextHolder中获得Authentication对象。 2.DetermineiftherequestrelatestoasecuredorpublicinvocationbylookingupthesecureobjectrequestagainsttheObjectDefinitionSource. 如果请求关系到一个安全的或者是公共的调用就通过去查找ObjectDefinitionSource确定是否一个安全的对象请求。 3.Foraninvocationthatissecured(thereisaConfigAttributeDefinitionforthesecureobjectinvocation): a.IfeithertheAuthentication.isAuthenticated()returnsfalse,orthealwaysReauthenticateistrue,authenticatetherequestagainsttheconfiguredAuthenticationManager.Whenauthenticated,replacetheAuthenticationobjectontheSecurityContextHolderwiththereturnedvalue. b.AuthorizetherequestagainsttheconfiguredAccessDecisionManager. c.Performanyrun-asreplacementviatheconfiguredRunAsManager. d.Passcontrolbacktotheconcretesubclass,whichwillactuallyproceedwithexecutingtheobject.AInterceptorStatusTokenisreturnedsothatafterthesubclasshasfinishedproceedingwithexecutionoftheobject,itsfinallyclausecanensuretheAbstractSecurityInterceptorisre-calledandtidiesupcorrectly. e.Theconcretesubclasswillre-calltheAbstractSecurityInterceptorviatheafterInvocation(InterceptorStatusToken,Object)method. f.IftheRunAsManagerreplacedtheAuthenticationobject,returntheSecurityContextHoldertotheobjectthatexistedafterthecalltoAuthenticationManager. g.IfanAfterInvocationManagerisdefined,invoketheinvocationmanagerandallowittoreplacetheobjectduetobereturnedtothecaller. 4.Foraninvocationthatispublic(thereisnoConfigAttributeDefinitionforthesecureobjectinvocation): a.Asdescribedabove,theconcretesubclasswillbereturnedanInterceptorStatusTokenwhichissubsequentlyre-presentedtotheAbstractSecurityInterceptorafterthesecureobjecthasbeenexecuted.TheAbstractSecurityInterceptorwilltakenofurtheractionwhenitsafterInvocation(InterceptorStatusToken,Object)iscalled. 5.Controlagainreturnstotheconcretesubclass,alongwiththeObjectthatshouldbereturnedtothecaller.Thesubclasswillthenreturnthatresultorexceptiontotheoriginalcaller. publicinterfaceObjectDefinitionSource ImplementedbyclassesthatstoreandcanidentifytheConfigAttributeDefinitionthatappliestoagivensecureobjectinvocation. 被这些可以存储和识别适用于给出的安全对象调用的ConfigAttributeDefinition类实现。 publicclassConfigAttributeDefinition extendsObject implementsSerializable HoldsagroupofConfigAttributesthatareassociatedwithagivensecureobjecttarget-effectivelyaCollection. Oncecreated,theobjectisimmutable. AlltheConfigAttributeDefinitionsassociatedwithagivenAbstractSecurityInterceptorarestoredinanObjectDefinitionSource. 拥有一组与给出的安全目标对象关联的ConfigAttributes---事实上是一个集合。 也就是这个对象内容保存有装有配置属性的集合。 一旦被创建,这个对象就是不变的。 所有与AbstractSecurityInterceptor关联的ConfigAttributeDefinitons都存储在ObjectDefinitionSource中。 也就是操作ObjectDefinitionSource实际上是为了获取ConfigAttributeDefinitions。 FilterSecurityInterceptor该filter也是个重量级的filter,主要是个拦截器的作用。 该filter需要配置一下属性: 1、authenticationManager校验密码并获取角色信息 2、objectDefinitionSource 3、accessDecisionManager--AffirmativeBased【具备两个属性: allowIfAllAbstainDecisions,decisionVoters】而decisionVoters可以配置为: a: RoleVoter根据ROLE_来确定是否通过 b: AuthenticatedVoter FilterSecurityInterceptor.doFilter中做了什么呢? 首先将request,response,chain封装成FilterInvocationfi,然后执行一下: 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,并且newConfigAttributeEditor(),再调用ConfigAttributeEditor.setAsText(authStr)和ConfigAttributeEditor.getValue(),将value强制转化成ConfigAttributeDefinition返回。 setAsText方面里面: newConfigAttributeDefinition,再将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获取
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- SpringSecurity API解读 API 解读