spring security3 cas线程安全吗

这里我首先对我上一篇博文的第三个实例做一下讲解,下面是applicationContext-security.
&??&&beans:beans ="http://www.springframework.org/schema/security"
="http://www.springframework.org/schema/beans"
="http://www.w3.org/2001/
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.0.xsd"&
&!-- 自动配置模式,拦截所有请求,有ROLE_USER才可以通过 --&
&http auto-config="true"&
&intercept-url pattern="/login.jsp*"
access="IS_AUTHENTICATED_ANONYMOUSLY" /&
&!-- 增加 ROLE_ADMIN角色--&
&intercept-url pattern="/admin.jsp" access="ROLE_ADMIN"/&
&intercept-url pattern="/**" access="ROLE_USER"/&
&form-login login-page="/login.jsp" authentication-failure-url="/login.jsp?login_error=1"/&
&!-- 认证管理器。用户名密码都集成在配置文件中 --&
&authentication-manager&
&authentication-provider&
&user-service&
&!-- 添加ROLE_ADMIN角色 --&
&user name="admin" password="admin" authorities="ROLE_USER,ROLE_ADMIN"/&
&user name="sharp" password="sharp" authorities="ROLE_USER"/&
&/user-service&
&/authentication-provider&
&/authentication-manager&
&!-- 指定中文资源 。默认命名空间是security,所以要加前缀beans: --&
&beans:bean id="messageSource"
&beans:property name="basename"
value="classpath:org/springframework/security/messages_zh_CN"/&
&/beans:bean&&/beans:beans&
该配置文件的注解如下:
&http auto-config="true"&,这一部分是配置如何拦截用户请求,auto-config="true"将自动配置几个常用的权限机制,包括form,anonymous,rememberMe.(这几种机制我也不太不明白)&。
&我们利用intercept-url来判断用户需要何种权限才能访问对应的url资源,可以在pattern中指定一个特定的url资源,也可以使用通配符来指定一组类似的url资源。例子中定义的两个intercepter-url,第一个用来控制对/admin.jsp的访问,第二个使用了通配符/**,说明它将控制对系统中所有url资源的访问。在实际使用中,Spring Security采用的是一种就近原则,就是说当用户访问的url资源满足多个intercepter-url时,系统将使用第一个符合条件的intercept-url进行权限控制。在我们这个例子中就是,当用户访问/admin.jsp时,虽然两个intercept-url都满足要求,但因为第一个intercept-url排在上面,所以Spring Security会使用第一个intercept-url中的配置处理对/admin.jsp的请求,也就是说,只有那些拥有了ROLE_ADMIN权限的用户才能访问/admin.jsp。access指定的权限部分比较有趣,大家可以注意到这些权限标示符都是以ROLE_开头的,实际上这与Spring Security中的Voter机制有着千丝万缕的联系,只有包含了特定前缀的字符串才会被Spring Security处理。目前来说我们只需要记住这一点就可以了,在我文章以后的部分中我们会详细讲解Voter的内容。(这里就解释了我在上面一个文章里,sharp拥有/**所有页面权限,为什么sharp用户却不能访问admin.jsp的原因)
user-service中定义了两个用户,admin和user。为了简便起见,我们使用明文定义了两个用户对应的密码,这只是为了当前演示的方便,之后的例子中我们会使用Spring Security提供的加密方式,避免用户密码被他人窃取。最最重要的部分是authorities,这里定义了这个用户登陆之后将会拥有的权限,它与上面intercept-url中定义的权限内容一一对应。每个用户可以同时拥有多个权限,例子中的admin用户就拥有ROLE_ADMIN和ROLE_USER两种权限,这使得admin用户在登陆之后可以访问ROLE_ADMIN和ROLE_USER允许访问的所有资源。与之对应的是,user用户就只拥有ROLE_USER权限,所以他只能访问ROLE_USER允许访问的资源,而不能访问ROLE_ADMIN允许访问的资源。
第四个实例:
这个实例里面用户信息存入到数据库里,我使用的是数据库是
create table USERS(
USERNAME VARCHAR2(64) not null,
PASSWORD VARCHAR2(64),
NUMBER)comment on column USERS.USERNAME
is '用户名';comment on column USERS.PASSWORD
is '密码';comment on column USERS.ENABLED
is '0--不可用;1--可用';alter table USERS
add constraint PK_USERS primary key (USERNAME)create table AUTHORITIES(
VARCHAR2(64) not null,
AUTHORITY VARCHAR2(64) not null)tablespace ANDROIDXIAJUN
pctfree 10
initrans 1
maxtrans 255
initial 64K
minextents 1
maxextents unlimited
);alter table AUTHORITIES
add constraint INDEX_USER_AUTH unique (USERNAME, AUTHORITY)alter table AUTHORITIES
add constraint USER_AUTHORITIES_FK foreign key (USERNAME)
references USERS (USERNAME);
数据库表创建好后,我们插入一些测试数据:
insert into users(username,password,enabled) values('admin','admin',1);insert into users(username,password,enabled) values('sharp','sharp',1);insert into authorities(username,authority) values('admin','ROLE_ADMIN');insert into authorities(username,authority) values('admin','ROLE_USER');insert into authorities(username,authority) values('sharp','ROLE_USER');
数据库的表建好,里面数据也有了,接下来就是修改我们原来的程序了。前面的三个实例都是在配置文件里配置好用户信息,而且还是明文的,如果换成数据库我们只要把这个部分的内容更改下:
&!-- 认证管理器。用户名密码都集成在配置文件中 --&
&authentication-manager&
&authentication-provider&
&user-service&
&!-- 添加ROLE_ADMIN角色 --&
&user name="admin" password="admin" authorities="ROLE_USER,ROLE_ADMIN"/&
&user name="sharp" password="sharp" authorities="ROLE_USER"/&
&/user-service&
&/authentication-provider&
&/authentication-manager&
修改的新内容是:
&!-- 认证管理器。用户名密码从数据库里读取 --&
&authentication-manager&
&authentication-provider&
&jdbc-user-service data-source-ref="dataSource"/&
&/authentication-provider&
&/authentication-manager&
另外我们还要增加一个数据源
dataSource,下面是我修改后完整的applicationContext-security.
&??&&beans:beans ="http://www.springframework.org/schema/security"
="http://www.springframework.org/schema/beans"
="http://www.w3.org/2001/
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.0.xsd"&
&!-- 自动配置模式,拦截所有请求,有ROLE_USER才可以通过 --&
&http auto-config="true"&
&intercept-url pattern="/login.jsp*"
access="IS_AUTHENTICATED_ANONYMOUSLY" /&
&!-- 增加 ROLE_ADMIN角色--&
&intercept-url pattern="/admin.jsp" access="ROLE_ADMIN"/&
&intercept-url pattern="/**" access="ROLE_USER"/&
&form-login login-page="/login.jsp" authentication-failure-url="/login.jsp?login_error=1"/&
&!-- 认证管理器。用户名密码从数据库里读取 --&
&authentication-manager&
&authentication-provider&
&jdbc-user-service data-source-ref="dataSource"/&
&/authentication-provider&
&/authentication-manager&
&!-- 指定中文资源 。默认命名空间是security,所以要加前缀beans: --&
&beans:bean id="messageSource"
&beans:property name="basename"
value="classpath:org/springframework/security/messages_zh_CN"/&
&/beans:bean&
&!-- 配置数据源信息
&beans:bean id="dataSource" &
&beans:property name="driverClass" value="${db.driverClass}"/&
&beans:property name="jdbcUrl" value="${db.jdbcUrl}"/&
&beans:property name="user" value="${db.user}"/&
&beans:property name="password" value="${db.password}"/&
&/beans:bean&
&!-- 读取资源文件 --&
&beans:bean id="propertyConfigurer" &
&beans:property name="locations"&
&beans:list&
&beans:value&classpath:constants.properties&/beans:value&
&/beans:list&
&/beans:property&
&/beans:bean&&/beans:beans&
按照我以前开发的习惯的,我会把spring里面很多配置信息放置到constants.properties里面,便于统一管理,constants.properties内容如下:
db.driverClass = oracle.jdbc.driver.OracleDriverdb.user
= sharpxiajundb.password
= sharpxiajundb.jdbcUrl
= jdbc:oracle:thin:@127.0.0.1:1521:orcl
为了和数据库链接我又增加了一些
至于测试和前面三个实例一样,这里不做过多表述了。
上一篇文章里,我们做的第二个实例是&自定义登录界面&,对里面一些特别的配置没有进行讲解,下面的内容就是对这个功能的具体讲解了:
&http auto-config="true"&
&intercept-url pattern="/login.jsp"
access="IS_AUTHENTICATED_ANONYMOUSLY" /&
&!-- 增加 ROLE_ADMIN角色--&
&intercept-url pattern="/admin.jsp" access="ROLE_ADMIN"/&
&intercept-url pattern="/**" access="ROLE_USER"/&
&form-login login-page="/login.jsp" authentication-failure-url="/login.jsp?login_error=1" default-target-url="/index.jsp"/&
1.&intercept-url pattern="/login.jsp"& access="IS_AUTHENTICATED_ANONYMOUSLY" /&让没登陆的用户也可以访问login.jsp。这是因为配置文件中的&/**&配置,要求用户访问任意一个系统资源时,必须拥有ROLE_USER角色,/login.jsp也不例外,如果我们不为/login.jsp单独设置访问权限,会造成用户连登录权限都没有,这个是不正确的
2. &form-login login-page="/login.jsp" authentication-failure-url="/login.jsp?login_error=1" default-target-url="/index.jsp"/&login-page表示用户登陆时显示我们自定义的login.jsp。这时我们访问系统显示的登陆页面将是我们上面创建的login.jsp。authentication-failure-url表示用户登陆失败时,跳转到哪个页面。当用户输入的登录名和密码不正确时,系统将再次跳转到/login.jsp,并添加一个error=true参数作为登陆失败的标示。default-target-url表示登陆成功时,跳转到哪个页面。
自制的登录页面里也有很多没有做注解的地方,现在补上页面里的注解,页面内容如下:
&body onLoad="document.f.j_username.focus();"&&c:if test="${not empty param.login_error}"&
&font color="red"&
登录失败,请重试.&br/&&br/&
原因:&c:out value="${SPRING_SECURITY_LAST_EXCEPTION.message}"/&
&/font&&/c:if&&form name="f" action="&c:url value='j_spring_security_check'/&" method="POST"&
&td&用户名:&/td&
&input type='text' name='j_username' value='&c:if test="${not empty param.login_error}"&&c:out value="${SPRING_SECURITY_LAST_USERNAME}"/&&/c:if&'/&
&td&&input type='password' name='j_password'&&/td&
&input type="checkbox" name="_spring_security_remember_me"&&/td&&td&两周内自动登录
&td colspan='2' align="center"&
&input name="submit" type="submit"&&&
&input name="reset" type="reset"&
&/table&&/form&&/body&
注解如下:
1.&body onload='document.f.j_username.focus();'&
表示在页面装载时onload调用函数'document.f.j_username.focus();该函数的意思是让表单中的j_username获得焦点,即把光标移动到该控件上;
2. action="&c:url value='j_spring_security_check'/&" /j_spring_security_check,提交登陆信息的URL地址。自定义form时,要把form的action设置为/j_spring_security_check。注意这里要使用绝对路径,避免登陆页面存放的页面可能带来的问题。
3. j_username,输入登陆名的参数名称。
4. j_password,输入密码的参数名称
5. _spring_security_remember_me,选择是否允许自动登录的参数名称。
可以直接把这个参数设置为一个checkbox,无需设置value,Spring Security
总结下了:Springsecurity应用讲解暂时告一段落,这个系列主要是为了应付实际工作,并不是我的研究重点,不过我很想在项目里面使用到它,到那时我一定会更加什么的讲解。另外我手头上springsecurity的资料并不太好,没有做深入研究的,如果哪位童鞋有更好的相关资料,希望能跟我分享下。
并发编程的Java抽象_幽灵学院 - 中国最权威的络安全门户站! Java体系是一个基于线程模型的本质编程平台,所以我们主要讨论线程模型。... 下一篇:java笔记:SpringSecurity应用(二) 收藏 挑错 推荐 打印...java笔记:SpringSecurity应用(二) - 百科教程_经验分享..._上学吧在实际使用中,Spring Security采用的是一种就近原则,就是说当用户访问的url资源满足多个intercepter-url时,系统将使用第一个符合条件的intercept-url进行权限控制。...《Spring Security 3》 【第六章】 高级配置和扩展(2) - zhang的...《SOA思想、技术与系统集成应用详解》读书笔记二-Java Web服务 - ...Android应用开发提高系列(2)——《Practical Java 中文版..._博客园 Android应用开发提高系列(1)——《Practical Java 中文版》读书笔记(上) 正文 注意:条目和用语可能与书籍有所出入,但尽量保持原样加一些自己的理解。 一、性能...Spring Security-2.0入门教程(基础篇) - 企业应用 - Java - ITeye... 企业应用 欢迎阅读咱们写的Spring Security教程,咱们既不想写一个简单的入门教程,也不想翻译已有的国外教程。咱们这个教程就是建立在咱们自己做的OA的基础上,一...我的SpringSecurity实践 - 马勒?格?彼得 - ITeye技术站 -- 用户Email表 跟SpringSecurity没有关系 DROP ...使用HTTPS协议 | jQuery-UI 学习笔记(一) date...看官方文档说在应用程序上下文必须有webapplicationCont...JAVA笔记2_百度文库JAVA笔记2_计算机软件及应用_IT/计算机_专业资料 暂无评价|0人阅读|0次下载|举报文档 JAVA笔记2_计算机软件及应用_IT/计算机_专业资料。基本数据包装为了方便操作...Java transaction笔记(二) - 半支香烟 - ITeye技术站Java应用服务器配置管理JMSBean 续Java transaction笔记(一, 继续我的transaction之旅。这次是XA transaction. Wiki对于XA的描述 引用 在计算技术上,XA规范是 The...【转】Spring Security 2 配置精讲 - JAVA—咖啡馆 - BlogJava 这个特性或许能够在一定程度上弥补Spring Security的死板规定,而在之后的应用中,我也会把它作为切入点,对资源进行管理。 另外,我需要补充一点的是,对于在http/...Spring Security2.0 登录(登出)成功 后置处理 - JAVA编..._红黑联盟由于目前项目中使用了Spring Security 2.0.1 权限管理框架,登入成功后可能就需要处理些登录日志等等后续操作,Security 3之后只需要在form-login中添加...springsecurity-2.x官方文档中文翻译初步整理完成,附上几个例子 -...预览:springsecurity/html/springsecurity.html 例子:因为站不允许下载war扩展名的文件,我已经把扩展名改成.zip了,请各位下载...Spring学习笔记之3.3 DI的深入(二) - Java - 次元立方 - 电脑...[]Spring提供两种方法注入:查找方法注入和方法替换注入。 因为Spring是通过CGLIB动态代理方式实现方法注入,也就是通过动态修改类的字节码来实现的,本质就是生成需方法注入...《Spring Security 3》 【第七章】 访问控制列表(ACL)(2) - zhang...PermissionFactory的角色是将许可的二进制掩码转换成逻辑许可值(它可以在应用的...相关笔记推荐 《Spring Security 3》 【第六章】 高级配置和扩展(7) 《...IT文档免费下载_日回顾_IT168文库 JavaEE-核心模式-及Spring实现-一- 下载:0次 阅读:123次 java笔记:SpringSecurity应用(一) 下载:1次 阅读:39次 java笔记:SpringSecurity应用(二) 下载:1次 ...Spring_Security_2.0.x中文参考文档.pdf - SpringSecurity - OPEN...Spring Security为基于J2EE的企业应用软件提供了一套全面的安全解决方案。正如你在本手册中看到的那样,我们尝试为您提供一套好用,高可配置的安全系统。 安全问题是一...用SpringSecurity和JCaptcha整合技术实现验证码登录 - 豆丁 摘要:Spring Security 是开源的 Java 安全框架,可以非常方便地与各应用系统集成...2006. 林信良. Java JDK6 学习笔记〔M〕. 北京: 清华大学出版 社,2007...我叫蔡泽华的微博_微博c java笔记:SpringSecurity应用(一) - 夏天的森林 - 博客园 :49 来自分享按钮 收藏 转发 评论 ...并发编程的Java抽象 java教程Java体系是一个基于线程模型的本质编程平台,所以我们主要讨论线程模型。 三、并发... 上一篇:java笔记:SpringSecurity应用(二) 下一篇:Tomcat启动时自动加载Servlet...读书笔记:《深入java虚拟机第二版》--- Java的体系结构 -..._博客园java Spring Security 总结二 6-中国学-中国综合信息门户站2??? class=&org.security.intercept.web.DataBaseFilterInvocationDefinition... java Spring Security 总结二 Spring JDBC数据库操作类 springside 笔记...并发编程的Java抽象 - JAVA编程语言程序开发技术文章 - 红黑联盟 Java体系是一个基于线程模型的本质编程平台,所以我们主要讨论线程模型。 三、...上一篇:Tomcat启动时自动加载Servlet 下一篇:java笔记:SpringSecurity应用(二) ...SpringSecurity2.0.4中如何配置 动态管理资源,用户及用户权限 - ...问答首页 → Java企业应用 0 0 SpringSecurity2.0.4中如何配置 动态管理资源,用户及用户权限10 如题。(注意是2.x,不是acegi 1.x) 固定的静态配置已经做了个...Java实训笔记(二) - 王者归来 - 博客频道 - CSDN意思就是一个父类的变量可以应用一个父类的对象,...Spring Apache
API HTML SDK IIS Fedora XML ... Java实训笔记(三)(1270) Java实训笔记(十)之...Spring Security 2 配置精讲 - Spring - Java - ITeye论坛8条回复&-&发帖时间:&日项目实践精解:基于Struts-Spring-Hibernate的Java应用开发(第二版)springsecurity2 url加参数过滤问题!!! - ITeye问答问答首页 → Java企业应用 0 0 springsecurity2 url加参数过滤问题!!!10 使用自定义从数据库查询 资源和角色对应信息,如下: &beans:bean id=&filterSecurityInte...Spring Security学习总结二(5)-JAVA 认证资料-教育联展JAVA 认证考试为您提供Spring Security学习总结二(5)资料,另提供Spring,JAVA 认证考试 模拟试题,JAVA 认证考试历年真题等相关JAVA 认证考试辅导资料免费下载!学习Spring3.X 企业应用开发实战笔记(二) - yza3137957的专栏 - ...IOC控制反转是Spring容器的核心,AOP、声明式事物等功能都是在此基础上开花结果。... JAVA快速排序(高效)(0) 学习Spring3.X 企业应用开发实战笔记(二)(0) ...Java菜鸟学习笔记--配置篇(二)Ubuntu JDK环境变量配置..._百度文库 Java菜鸟学习笔记--配置篇(二)Ubuntu JDK环境变量配置与常见问题_计算机软件及应用_IT/计算机_专业资料。重庆达渝仁科技官:cqdyr 1.1 进入官下载 ...《Spring Security 3》 【第十章】 使用中心认证服务(CAS)进行单...浏览(7067)|评论(0) 交流分类:Java|笔记分类: ... 与我们配置Spring Security连接外部的(非嵌入式的)... 重启JBCP Pets应用就会使用SAML响应进行ticket校验了...spring-security3 配置和使用(二)承上 - java技术交流 - ITeye... & beans:beans
xmlns = &http://springframework.org/schema/security&
xmlns:beans = &http://springframework.org...基于java config的springSecurity(四)--启用全局方法安全 - xie...参考资料:http://docs.spring.io/spring-security/site/docs/3.2.5.RELEASE/reference/htmlsingle 前面实现了认证,一般都满足不了应用的需求.使用@EnableGlobal...人气:1975615
访问用户量:2985
笔记经验:3830
总积分:261644
级别:VIP5
搜索本笔记
ta的交流分类
ta的全部笔记
浏览(4848)|(0)
&&交流分类:|笔记分类:
FilterSecurityInterceptor过滤器对应的类路径为&org.springframework.security.web.access.intercept.FilterSecurityInterceptor&这个filter是filterchain中比较复杂,也是比较核心的过滤器,主要负责授权的工作&在看这个filter源码之前,先来看看spring是如何构造filter这个bean的&具体的构造过程的代码片段为&
void&createFilterSecurityInterceptor(BeanReference&authManager)&{&&
&&&&boolean&useExpressions&=&FilterInvocationSecurityMetadataSourceParser.isUseExpressions(httpElt);&&
&&&&BeanDefinition&securityMds&=&FilterInvocationSecurityMetadataSourceParser.createSecurityMetadataSource(interceptUrls,&httpElt,&pc);&&
&&&&RootBeanDefinition&accessDecisionM&&
&&&&ManagedList&BeanDefinition&&voters&=&&new&ManagedList&BeanDefinition&(2);&&
&&&&if&(useExpressions)&{&&
&&&&&&&&voters.add(new&RootBeanDefinition(WebExpressionVoter.class));&&
&&&&}&else&{&&
&&&&&&&&voters.add(new&RootBeanDefinition(RoleVoter.class));&&
&&&&&&&&voters.add(new&RootBeanDefinition(AuthenticatedVoter.class));&&
&&&&accessDecisionMgr&=&new&RootBeanDefinition(AffirmativeBased.class);&&
&&&&accessDecisionMgr.getPropertyValues().addPropertyValue(&decisionVoters&,&voters);&&
&&&&accessDecisionMgr.setSource(pc.extractSource(httpElt));&&
&&&&String&accessManagerId&=&httpElt.getAttribute(ATT_ACCESS_MGR);&&
&&&&if&(!StringUtils.hasText(accessManagerId))&{&&
&&&&&&&&accessManagerId&=&pc.getReaderContext().generateBeanName(accessDecisionMgr);&&
&&&&&&&&pc.registerBeanComponent(new&BeanComponentDefinition(accessDecisionMgr,&accessManagerId));&&
&&&&BeanDefinitionBuilder&builder&=&BeanDefinitionBuilder.rootBeanDefinition(FilterSecurityInterceptor.class);&&
&&&&builder.addPropertyReference(&accessDecisionManager&,&accessManagerId);&&
&&&&builder.addPropertyValue(&authenticationManager&,&authManager);&&
&&&&if&(&false&.equals(httpElt.getAttribute(ATT_ONCE_PER_REQUEST)))&{&&
&&&&&&&&builder.addPropertyValue(&observeOncePerRequest&,&Boolean.FALSE);&&
&&&&builder.addPropertyValue(&securityMetadataSource&,&securityMds);&&
&&&&BeanDefinition&fsiBean&=&builder.getBeanDefinition();&&
&&&&String&fsiId&=&pc.getReaderContext().generateBeanName(fsiBean);&&
&&&&pc.registerBeanComponent(new&BeanComponentDefinition(fsiBean,fsiId));&&
&&&&BeanDefinition&wipe&=&new&RootBeanDefinition(DefaultWebInvocationPrivilegeEvaluator.class);&&
&&&&wipe.getConstructorArgumentValues().addGenericArgumentValue(new&RuntimeBeanReference(fsiId));&&
&&&&pc.registerBeanComponent(new&BeanComponentDefinition(wipe,&pc.getReaderContext().generateBeanName(wipe)));&&
&&&&this.fsi&=&new&RuntimeBeanReference(fsiId);&&
现在再仔细分析创建元数据资源的bean过程&
static&BeanDefinition&createSecurityMetadataSource(List&Element&&interceptUrls,&Element&elt,&ParserContext&pc)&{&&
&&&&UrlMatcher&matcher&=&HttpSecurityBeanDefinitionParser.createUrlMatcher(elt);&&
&&&&boolean&useExpressions&=&isUseExpressions(elt);&&
&&&&ManagedMap&BeanDefinition,&BeanDefinition&&requestToAttributesMap&=&parseInterceptUrlsForFilterInvocationRequestMap(&&
&&&&&&&&&&&&interceptUrls,&useExpressions,&pc);&&
&&&&BeanDefinitionBuilder&fidsB&&
&&&&if&(useExpressions)&{&&
&&&&&&&&&&
&&&&&&&&Element&expressionHandlerElt&=&DomUtils.getChildElementByTagName(elt,&Elements.EXPRESSION_HANDLER);&&
&&&&&&&&String&expressionHandlerRef&=&expressionHandlerElt&==&null&?&null&:&expressionHandlerElt.getAttribute(&ref&);&&
&&&&&&&&if&(StringUtils.hasText(expressionHandlerRef))&{&&
&&&&&&&&&&&&(&Using&bean&'&&+&expressionHandlerRef&+&&'&as&web&SecurityExpressionHandler&implementation&);&&
&&&&&&&&}&else&{&&
&&&&&&&&&&&&BeanDefinition&expressionHandler&=&BeanDefinitionBuilder.rootBeanDefinition(DefaultWebSecurityExpressionHandler.class).getBeanDefinition();&&
&&&&&&&&&&&&expressionHandlerRef&=&pc.getReaderContext().generateBeanName(expressionHandler);&&
&&&&&&&&&&&&pc.registerBeanComponent(new&BeanComponentDefinition(expressionHandler,&expressionHandlerRef));&&
&&&&&&&&}&&
&&&&&&&&&&
&&&&&&&&fidsBuilder&=&BeanDefinitionBuilder.rootBeanDefinition(ExpressionBasedFilterInvocationSecurityMetadataSource.class);&&
&&&&&&&&&&
&&&&&&&&fidsBuilder.addConstructorArgValue(matcher);&&
&&&&&&&&fidsBuilder.addConstructorArgValue(requestToAttributesMap);&&
&&&&&&&&fidsBuilder.addConstructorArgReference(expressionHandlerRef);&&
&&&&}&else&{&&
&&&&&&&&&&
&&&&&&&&fidsBuilder&=&BeanDefinitionBuilder.rootBeanDefinition(DefaultFilterInvocationSecurityMetadataSource.class);&&
&&&&&&&&&&
&&&&&&&&fidsBuilder.addConstructorArgValue(matcher);&&
&&&&&&&&fidsBuilder.addConstructorArgValue(requestToAttributesMap);&&
&&&&fidsBuilder.addPropertyValue(&stripQueryStringFromUrls&,&matcher&instanceof&AntUrlPathMatcher);&&
&&&&fidsBuilder.getRawBeanDefinition().setSource(pc.extractSource(elt));&&
&&&&return&fidsBuilder.getBeanDefinition();&&
通过以上的bean构造过程,FilterSecurityInterceptor所依赖的决策管理器、认证管理器、安全元数据资源都具备了,该让FilterSecurityInterceptor干活了,其源码为&
public&void&doFilter(ServletRequest&request,&ServletResponse&response,&FilterChain&chain)&&
&&&&&&&&throws&IOException,&ServletException&{&&
&&&&FilterInvocation&fi&=&new&FilterInvocation(request,&response,&chain);&&
&&&&invoke(fi);&&
public&void&invoke(FilterInvocation&fi)&throws&IOException,&ServletException&{&&
&&&&if&((fi.getRequest()&!=&null)&&&&(fi.getRequest().getAttribute(FILTER_APPLIED)&!=&null)&&
&&&&&&&&&&&&&&&observeOncePerRequest)&{&&
&&&&&&&&if&(fi.getRequest()&!=&null)&{&&
&&&&&&&&&&&&fi.getRequest().setAttribute(FILTER_APPLIED,&Boolean.TRUE);&&
&&&&&&&&}&&
&&&&&&&&&&
&&&&&&&&InterceptorStatusToken&token&=&super.beforeInvocation(fi);&&
&&&&&&&&try&{&&
&&&&&&&&&&&&&&
&&&&&&&&&&&&fi.getChain().doFilter(fi.getRequest(),&fi.getResponse());&&
&&&&&&&&}&finally&{&&
&&&&&&&&&&&&&&
&&&&&&&&&&&&super.afterInvocation(token,&null);&&
&&&&&&&&}&&
继续看父类的beforeInvocation方法,其中省略了一些不重要的代码片段&
protected&InterceptorStatusToken&beforeInvocation(Object&object)&{&&
&&&&Collection&ConfigAttribute&&attributes&=&this.obtainSecurityMetadataSource().getAttributes(object);&&
&&&&Authentication&authenticated&=&authenticateIfRequired();&&
&&&&try&{&&
&&&&&&&&&&
&&&&&&&&this.accessDecisionManager.decide(authenticated,&object,&attributes);&&
&&&&catch&(AccessDeniedException&accessDeniedException)&{&&
&&&&&&&&publishEvent(new&AuthorizationFailureEvent(object,&attributes,&authenticated,&&
&&&&&&&&&&&&&&&&accessDeniedException));&&
&&&&&&&&throw&accessDeniedE&&
Collection&ConfigAttribute&&attributes&=&this.obtainSecurityMetadataSource().getAttributes(object);&&
这里获取的是权限列表信息,比如说有这个配置&&security:intercept-url pattern=&/index.jsp*& access=&ROLE_USER,ROLE_ADMIN&/&&如果现在发起一个请求时index.jsp,那么根据这个请求返回的attributes集合就是分别包含ROLE_USER,ROLE_ADMIN属性的两个SecurityConfig对象&至于请求url如何匹配的,大家可以通过阅读DefaultFilterInvocationSecurityMetadataSource类的源码,实际上,这里用到了spring的路径匹配工具类org.springframework.util.AntPathMatcher&AntPathMatcher匹配方式的通配符有三种:&&&& ?(匹配任何单字符),*(匹配0或者任意数量的字符),**(匹配0或者更多的目录)&由于之前在bean的定义过程已经知道决策管理器是AffirmativeBased,接着看AffirmativeBased的决策过程&
public&void&decide(Authentication&authentication,&Object&object,&Collection&ConfigAttribute&&configAttributes)&&
&&&&&&&&throws&AccessDeniedException&{&&
&&&&int&deny&=&0;&&
&&&&for&(AccessDecisionVoter&voter&:&getDecisionVoters())&{&&
&&&&&&&&&&
&&&&&&&&&&&&
&&&&&&&&int&result&=&voter.vote(authentication,&object,&configAttributes);&&
&&&&&&&&if&(logger.isDebugEnabled())&{&&
&&&&&&&&&&&&logger.debug(&Voter:&&&+&voter&+&&,&returned:&&&+&result);&&
&&&&&&&&}&&
&&&&&&&&switch&(result)&{&&
&&&&&&&&case&AccessDecisionVoter.ACCESS_GRANTED:&&
&&&&&&&&&&&&return;&&
&&&&&&&&case&AccessDecisionVoter.ACCESS_DENIED:&&
&&&&&&&&&&&&deny++;&&
&&&&&&&&&&&&break;&&
&&&&&&&&default:&&
&&&&&&&&&&&&break;&&
&&&&&&&&}&&
&&&&if&(deny&&&0)&{&&
&&&&&&&&throw&new&AccessDeniedException(messages.getMessage(&AbstractAccessDecisionManager.accessDenied&,&&
&&&&&&&&&&&&&&&&&Access&is&denied&));&&
&&&&checkAllowIfAllAbstainDecisions();&&
实际上,有三种决策管理器,分别为AffirmativeBased、ConsensusBased、UnanimousBased,各自决策的区别是:&AffirmativeBased:只要有一个voter投同意票,就授权成功&ConsensusBased:只要投同意票的大于投反对票的,就授权成功&UnanimousBased:需要一致通过才授权成功具体决策规则很简单,只是根据voter返回的结果做处理&接下来,分别看RoleVoter、AuthenticatedVoter的源码&RoleVoter:&
public&int&vote(Authentication&authentication,&Object&object,&Collection&ConfigAttribute&&attributes)&{&&
&&&&int&result&=&ACCESS_ABSTAIN;&&
&&&&Collection&GrantedAuthority&&authorities&=&extractAuthorities(authentication);&&
&&&&for&(ConfigAttribute&attribute&:&attributes)&{&&
&&&&&&&&if&(this.supports(attribute))&{&&
&&&&&&&&&&&&result&=&ACCESS_DENIED;&&
&&&&&&&&&&&&&&
&&&&&&&&&&&&&&
&&&&&&&&&&&&for&(GrantedAuthority&authority&:&authorities)&{&&
&&&&&&&&&&&&&&&&if&(attribute.getAttribute().equals(authority.getAuthority()))&{&&
&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&&return&ACCESS_GRANTED;&&
&&&&&&&&&&&&&&&&}&&
&&&&&&&&&&&&}&&
&&&&&&&&}&&
&&&&return&&&
AuthenticatedVoter:&
public&int&vote(Authentication&authentication,&Object&object,&Collection&ConfigAttribute&&attributes)&{&&
&&&&int&result&=&ACCESS_ABSTAIN;&&
&&&&for&(ConfigAttribute&attribute&:&attributes)&{&&
&&&&&&&&if&(this.supports(attribute))&{&&
&&&&&&&&&&&&result&=&ACCESS_DENIED;&&
&&&&&&&&&&&&if&(IS_AUTHENTICATED_FULLY.equals(attribute.getAttribute()))&{&&
&&&&&&&&&&&&&&&&if&(isFullyAuthenticated(authentication))&{&&
&&&&&&&&&&&&&&&&&&&&return&ACCESS_GRANTED;&&
&&&&&&&&&&&&&&&&}&&
&&&&&&&&&&&&}&&
&&&&&&&&&&&&if&(IS_AUTHENTICATED_REMEMBERED.equals(attribute.getAttribute()))&{&&
&&&&&&&&&&&&&&&&if&(authenticationTrustResolver.isRememberMe(authentication)&&
&&&&&&&&&&&&&&&&&&&&||&isFullyAuthenticated(authentication))&{&&
&&&&&&&&&&&&&&&&&&&&return&ACCESS_GRANTED;&&
&&&&&&&&&&&&&&&&}&&
&&&&&&&&&&&&}&&
&&&&&&&&&&&&if&(IS_AUTHENTICATED_ANONYMOUSLY.equals(attribute.getAttribute()))&{&&
&&&&&&&&&&&&&&&&if&(authenticationTrustResolver.isAnonymous(authentication)&||&isFullyAuthenticated(authentication)&&
&&&&&&&&&&&&&&&&&&&&||&authenticationTrustResolver.isRememberMe(authentication))&{&&
&&&&&&&&&&&&&&&&&&&&return&ACCESS_GRANTED;&&
&&&&&&&&&&&&&&&&}&&
&&&&&&&&&&&&}&&
&&&&&&&&}&&
&&&&return&&&
由于RoleVoter在list列表中的位置处于AuthenticatedVoter前面,只要RoleVoter通过,就不会再执行AuthenticatedVoter了。实际上AuthenticatedVoter只会对IS_AUTHENTICATED_FULLY、IS_AUTHENTICATED_REMEMBERED、IS_AUTHENTICATED_ANONYMOUSLY三种权限做vote处理。
转载自【】
作者博客:
相关笔记推荐
精品视频课程推荐
本课程专注于数据结构和算法的内容,使用Java来进行代码示例,不空洞的讲解概念和理论,重点放在代码的实现和示例上。
从零开始、全面系统、成体系的讲解数据结构和基本算法,循序渐进的讲述构建软件系统所常见的数据结构和算法。
内容概述:Shiro是目前最热门、最易用、功能超强大的Java权限管理框架,强烈推荐,每个项目都必备的权限管理技术!通过本课程,你将从零开始直到彻底掌握Shiro的相关开发知识,达到可以进行实际项目开发的能力。包括:权限管理基础、Shiro入门、配置、身份认证、授权、Realms、Session管理、和Spring的集成、Web、Cache等众多开发细节技术
技术要点:源码级分析Shiro的授权过程、自定义开发Realm、多个Realms的开发配置、自定义开发AuthenticationStrategy、自定义开发自定义SessionDAO、和Struts2+Spring3的集成(包括修正struts2的bug)、Shiro和SpringMVC+Spring3的集成、包装使用其他的Cache框架、缓存数据同步更新的解决方案等等实际开发中常用的内容
系统、完整的学习Spring Web MVC开发的知识。包括:Spring Web MVC入门;理解DispatcherServlet;注解式控制器开发详解;数据类型转换;数据格式化;数据验证; 拦截器;对Ajax的支持;文件上传下载;表单标签等内容;最后以一个综合的CRUD带翻页的应用示例来综合所学的知识
系统、完整的学习Spring Data JPA开发的知识。包括:Spring Data JPA入门;JpaRepository基本功能 ;JpaRepository的查询;客户化扩展JpaRepository;Specifications查询。
深入浅出的讲解JavaBen的写法、JavaBean的用法、JavaBean的实现机制、JavaBean对应翻译的代码理解。
浏览(4848)|(0)
&&交流分类:|笔记分类:
版权所有 Copyright(C) 私塾在线学习网

我要回帖

更多关于 spring security3.0 的文章

 

随机推荐