|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
专门做了这个例子;而java的这个例子好像就是为了教学而写的,很多教学目的的例子是不考虑优化、性能的。
我们从FilterSecurityInterceptor我们从动手看看如何举行受权的:
Java代码
//这里是拦阻器拦阻HTTP哀求的出口
publicvoiddoFilter(ServletRequestrequest,ServletResponseresponse,FilterChainchain)
throwsIOException,ServletException{
FilterInvocationfi=newFilterInvocation(request,response,chain);
invoke(fi);
}
//这是详细的拦阻挪用
publicvoidinvoke(FilterInvocationfi)throwsIOException,ServletException{
if((fi.getRequest()!=null)&&(fi.getRequest().getAttribute(FILTER_APPLIED)!=null)
&&observeOncePerRequest){
//在第一次举行过平安反省以后就不会再做了
fi.getChain().doFilter(fi.getRequest(),fi.getResponse());
}else{
//这是第一次收到响应的哀求,必要做平安检测,同时把标记为设置好- FILTER_APPLIED,下次就再有哀求就不会作不异的平安反省了
if(fi.getRequest()!=null){
fi.getRequest().setAttribute(FILTER_APPLIED,Boolean.TRUE);
}
//这里是做平安反省的中央
InterceptorStatusTokentoken=super.beforeInvocation(fi);
//接着向拦阻器链实行
try{
fi.getChain().doFilter(fi.getRequest(),fi.getResponse());
}finally{
super.afterInvocation(token,null);
}
}
}
我们看看在AbstractSecurityInterceptor是如何对HTTP哀求作平安检测的:
Java代码
protectedInterceptorStatusTokenbeforeInvocation(Objectobject){
Assert.notNull(object,"Objectwasnull");
if(!getSecureObjectClass().isAssignableFrom(object.getClass())){
thrownewIllegalArgumentException("Securityinvocationattemptedforobject"
+object.getClass().getName()
+"butAbstractSecurityInterceptoronlyconfiguredtosupportsecureobjectsoftype:"
+getSecureObjectClass());
}
//这里读取设置FilterSecurityInterceptor的ObjectDefinitionSource属性,这些属性设置了资本的平安设置
ConfigAttributeDefinitionattr=this.obtainObjectDefinitionSource().getAttributes(object);
if(attr==null){
if(rejectPublicInvocations){
thrownewIllegalArgumentException(
"NopublicinvocationsareallowedviathisAbstractSecurityInterceptor."
+"Thisindicatesaconfigurationerrorbecausethe"
+"AbstractSecurityInterceptor.rejectPublicInvocationspropertyissettotrue");
}
if(logger.isDebugEnabled()){
logger.debug("Publicobject-authenticationnotattempted");
}
publishEvent(newPublicInvocationEvent(object));
returnnull;//nofurtherworkpost-invocation
}
if(logger.isDebugEnabled()){
logger.debug("Secureobject:"+object.toString()+";ConfigAttributes:"+attr.toString());
}
//这里从SecurityContextHolder中往取Authentication对象,一样平常在登录时会放到SecurityContextHolder中往
if(SecurityContextHolder.getContext().getAuthentication()==null){
credentialsNotFound(messages.getMessage("AbstractSecurityInterceptor.authenticationNotFound",
"AnAuthenticationobjectwasnotfoundintheSecurityContext"),object,attr);
}
//假如后面没有处置鉴权,这里必要对鉴权举行处置
Authenticationauthenticated;
if(!SecurityContextHolder.getContext().getAuthentication().isAuthenticated()||alwaysReauthenticate){
try{//挪用设置好的AuthenticationManager处置鉴权,假如鉴权不成功,抛出非常停止处置
authenticated=this.authenticationManager.authenticate(SecurityContextHolder.getContext()
.getAuthentication());
}catch(AuthenticationExceptionauthenticationException){
throwauthenticationException;
}
//Wedontauthenticated.setAuthentication(true),becauseeachprovidershoulddothat
if(logger.isDebugEnabled()){
logger.debug("SuccessfullyAuthenticated:"+authenticated.toString());
}
//这里把鉴权乐成后失掉的Authentication保留到SecurityContextHolder中供下次利用
SecurityContextHolder.getContext().setAuthentication(authenticated);
}else{//这里处置后面已经由过程鉴权的哀求,先从SecurityContextHolder中往获得Authentication
authenticated=SecurityContextHolder.getContext().getAuthentication();
if(logger.isDebugEnabled()){
logger.debug("PreviouslyAuthenticated:"+authenticated.toString());
}
}
//这是处置受权的历程
try{
//挪用设置好的AccessDecisionManager来举行受权
this.accessDecisionManager.decide(authenticated,object,attr);
}catch(AccessDeniedExceptionaccessDeniedException){
//受权不乐成向外公布事务
AuthorizationFailureEventevent=newAuthorizationFailureEvent(object,attr,authenticated,
accessDeniedException);
publishEvent(event);
throwaccessDeniedException;
}
if(logger.isDebugEnabled()){
logger.debug("Authorizationsuccessful");
}
AuthorizedEventevent=newAuthorizedEvent(object,attr,authenticated);
publishEvent(event);
//这里构建一个RunAsManager来替换以后的Authentication对象,默许情形下利用的是NullRunAsManager会把SecurityContextHolder中的Authentication对象清空
AuthenticationrunAs=this.runAsManager.buildRunAs(authenticated,object,attr);
if(runAs==null){
if(logger.isDebugEnabled()){
logger.debug("RunAsManagerdidnotchangeAuthenticationobject");
}
//nofurtherworkpost-invocation
returnnewInterceptorStatusToken(authenticated,false,attr,object);
}else{
if(logger.isDebugEnabled()){
logger.debug("SwitchingtoRunAsAuthentication:"+runAs.toString());
}
SecurityContextHolder.getContext().setAuthentication(runAs);
//reverttotoken.Authenticatedpost-invocation
returnnewInterceptorStatusToken(authenticated,true,attr,object);
}
}
<p>
令人可喜的是java现在已经开源了,所以我想我上述的想法也许有一天会实现,因为java一直都是不断创新的语言,每次创新都会给我们惊喜,这也是我喜欢java的一个原因。 |
|