SpringSecurity API解读.docx

上传人:b****5 文档编号:6060494 上传时间:2023-01-03 格式:DOCX 页数:15 大小:28.82KB
下载 相关 举报
SpringSecurity API解读.docx_第1页
第1页 / 共15页
SpringSecurity API解读.docx_第2页
第2页 / 共15页
SpringSecurity API解读.docx_第3页
第3页 / 共15页
SpringSecurity API解读.docx_第4页
第4页 / 共15页
SpringSecurity API解读.docx_第5页
第5页 / 共15页
点击查看更多>>
下载资源
资源描述

SpringSecurity API解读.docx

《SpringSecurity API解读.docx》由会员分享,可在线阅读,更多相关《SpringSecurity API解读.docx(15页珍藏版)》请在冰豆网上搜索。

SpringSecurity API解读.docx

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

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 解决方案 > 营销活动策划

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1