﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-无极，无际，无迹-文章分类-软件架构</title><link>http://www.blogjava.net/taochen1984/category/42649.html</link><description /><language>zh-cn</language><lastBuildDate>Wed, 27 Jan 2010 08:36:19 GMT</lastBuildDate><pubDate>Wed, 27 Jan 2010 08:36:19 GMT</pubDate><ttl>60</ttl><item><title>SpringSecurity使用记录（六）-- 本地配置二</title><link>http://www.blogjava.net/taochen1984/articles/310744.html</link><dc:creator>taochen</dc:creator><author>taochen</author><pubDate>Mon, 25 Jan 2010 08:29:00 GMT</pubDate><guid>http://www.blogjava.net/taochen1984/articles/310744.html</guid><wfw:comment>http://www.blogjava.net/taochen1984/comments/310744.html</wfw:comment><comments>http://www.blogjava.net/taochen1984/articles/310744.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/taochen1984/comments/commentRss/310744.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/taochen1984/services/trackbacks/310744.html</trackback:ping><description><![CDATA[接着来。<br />
2.过滤器的配置：<br />
&nbsp; 我们已经配置了那些过滤器了，但是要跟spring context中的对象对应，于是乎，做了如下配置：<br />
&nbsp; &lt;beans:bean id="securityContextPersistenceFilter" <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class="org.springframework.security.web.context.SecurityContextPersistenceFilter"&gt;<br />
&nbsp; &lt;/beans:bean&gt;<br />
&nbsp; &lt;beans:bean id="logoutFilter" <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class="org.springframework.security.web.authentication.logout.LogoutFilter" &gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;beans:constructor-arg type="java.lang.String" value="/"/&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;beans:constructor-arg ref="securityContextLogoutHandler"/&gt;<br />
&nbsp; &lt;/beans:bean&gt;<br />
&nbsp; &lt;beans:bean id="basicAuthenticationFilter" <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class="org.springframework.security.web.authentication.www.BasicAuthenticationFilter"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;beans:property name="authenticationManager" ref="authenticationManager"&gt;&lt;/beans:property&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;beans:property name="authenticationEntryPoint" ref="authenticationProcessingFilterEntryPoint"&gt;&lt;/beans:property&gt;<br />
&nbsp; &lt;/beans:bean&gt;<br />
&nbsp; &lt;beans:bean id="requestCacheAwareFilter" <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class="org.springframework.security.web.savedrequest.RequestCacheAwareFilter"&gt;<br />
&nbsp; &lt;/beans:bean&gt;<br />
&nbsp; &lt;beans:bean id="securityContextHolderAwareRequestFilter" <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class="org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter"&gt;<br />
&nbsp; &lt;/beans:bean&gt;<br />
&nbsp; &lt;beans:bean id="anonymousAuthenticationFilter" <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class="org.springframework.security.web.authentication.AnonymousAuthenticationFilter"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;beans:property name="userAttribute" ref="anonymousUserAttribute"&gt;&lt;/beans:property&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;beans:property name="key"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; value="anonymousUser"/&gt;<br />
&nbsp; &lt;/beans:bean&gt;<br />
&nbsp; &lt;beans:bean id="sessionManagementFilter" <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class="org.springframework.security.web.session.SessionManagementFilter"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;beans:constructor-arg&nbsp; type="org.springframework.security.web.context.SecurityContextRepository" ref="sessionSecurityContextRepository"/&gt;<br />
&nbsp; &lt;/beans:bean&gt;<br />
&nbsp; &lt;beans:bean id="exceptionTranslationFilter" <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class="org.springframework.security.web.access.ExceptionTranslationFilter"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;beans:property name="authenticationEntryPoint" ref="authenticationProcessingFilterEntryPoint"/&gt;<br />
&nbsp; &lt;/beans:bean&gt;<br />
&nbsp; &lt;beans:bean id="filterSecurityInterceptor" <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;beans:property name="authenticationManager"&nbsp; ref="authenticationManager" /&gt; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;beans:property name="accessDecisionManager"&nbsp; ref="accessDecisionManager" /&gt; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;beans:property name="securityMetadataSource" ref="securityMetadataSource" /&gt;<br />
&nbsp; &lt;/beans:bean&gt;<br />
&nbsp; <br />
&nbsp; &lt;!-- The following beans are configured for the filters upstairs --&gt;<br />
&nbsp; &lt;!-- ///////////////////////////////////////// --&gt;<br />
&nbsp; &lt;!-- ////for LogoutFilter///////////////////// --&gt;<br />
&nbsp; &lt;!-- ///////////////////////////////////////// --&gt;<br />
&nbsp; &lt;beans:bean id="securityContextLogoutHandler" <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler"&gt;<br />
&nbsp; &lt;/beans:bean&gt;<br />
&nbsp; &lt;!-- ///////////////////////////////////////// --&gt;<br />
&nbsp; &lt;!-- ////for AnonymousAuthenticationFilter//// --&gt;<br />
&nbsp; &lt;!-- ///////////////////////////////////////// --&gt;<br />
&nbsp; &lt;beans:bean id="anonymousUserAttribute" <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class="org.springframework.security.core.userdetails.memory.UserAttribute"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;beans:property name="authorities"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;beans:list&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;beans:ref&nbsp; bean="anonymousUserGrantedAuthority" /&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/beans:list&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/beans:property&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;beans:property name="password" value="anonymousUser"/&gt;<br />
&nbsp; &lt;/beans:bean&gt;<br />
&nbsp; &lt;beans:bean id="anonymousUserGrantedAuthority" <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class="org.springframework.security.core.authority.GrantedAuthorityImpl"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;beans:constructor-arg type="java.lang.String" value="ROLE_ANONYMOUS"/&gt;<br />
&nbsp; &lt;/beans:bean&gt;<br />
&nbsp; &lt;!-- ///////////////////////////////////////// --&gt;<br />
&nbsp; &lt;!-- ////for SessionManagementFilter////////// --&gt;<br />
&nbsp; &lt;!-- ///////////////////////////////////////// --&gt;<br />
&nbsp; &lt;beans:bean id="sessionSecurityContextRepository" <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class="org.springframework.security.web.context.HttpSessionSecurityContextRepository"&gt;<br />
&nbsp; &lt;/beans:bean&gt;<br />
&nbsp; &lt;!-- ///////////////////////////////////////// --&gt;<br />
&nbsp; &lt;!-- ////for FilterSecurityInterceptor//////// --&gt;<br />
&nbsp; &lt;!-- ///////////////////////////////////////// --&gt;<br />
&nbsp; &lt;beans:bean id="accessDecisionManager" <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class="org.springframework.security.access.vote.AffirmativeBased"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;beans:property name="decisionVoters"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;beans:list&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;beans:ref bean="webExpressionVoter"/&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/beans:list&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/beans:property&gt;<br />
&nbsp; &lt;/beans:bean&gt;<br />
&nbsp; &lt;beans:bean id="webExpressionVoter" <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class="com.saveworld.authentication.web.access.expression.MyWebExpressionVoter"&gt;<br />
&nbsp; &lt;/beans:bean&gt;<br />
&nbsp; &lt;beans:bean id="securityMetadataSource" <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class="com.saveworld.authentication.web.access.intercept.MyFilterInvocationSecurityMetadataSource"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;beans:constructor-arg type="org.springframework.security.web.util.UrlMatcher" ref="urlMatcher" /&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;beans:constructor-arg type="javax.sql.DataSource" ref="proxoolDataSource" /&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;beans:constructor-arg type="org.springframework.security.web.access.expression.WebSecurityExpressionHandler" <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ref="expressionHandler" /&gt;<br />
&nbsp; &lt;/beans:bean&gt;<br />
&nbsp; &lt;beans:bean id="urlMatcher"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class="org.springframework.security.web.util.AntUrlPathMatcher" &gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;beans:constructor-arg type="boolean" value="true" /&gt;<br />
&nbsp; &lt;/beans:bean&gt;<br />
&nbsp; &lt;beans:bean id="expressionHandler" <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class="org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler"&gt;<br />
&nbsp; &lt;/beans:bean&gt;<br />
这里做几点说明：<br />
&nbsp;&nbsp; (1) 数据库中的权限相关的表：<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ROLES<br />
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp;&nbsp; AUTHORITIES<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; USER_AUTHS<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ROLE_AUTHS<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; USERS<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这里的表结构还不是最终的，所以就不发上来误导兄弟姐妹们了。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 关键是看我们如何加载这些持久化的东西。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这个就要看看filterSecurityInterceptor了，它里面使用了一个securityMetadataSource，本地的securityMetadataSource实现代码：<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public class MyFilterInvocationSecurityMetadataSource extends DefaultFilterInvocationSecurityMetadataSource{<br />
&nbsp;&nbsp;&nbsp; private final static Log logger = LogFactory.getLog(ExpressionBasedFilterInvocationSecurityMetadataSource.class);<br />
&nbsp;&nbsp;&nbsp; private DataSource datasource;<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; public MyFilterInvocationSecurityMetadataSource(UrlMatcher urlMatcher,<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DataSource datasource,<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WebSecurityExpressionHandler expressionHandler) {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; super(urlMatcher, processMap(initializeFromDb(datasource,null),expressionHandler.getExpressionParser()));<br />
&nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp; //This method is usefulless for now!<br />
&nbsp;&nbsp;&nbsp; //Because this method is used for parsing the expression kind<br />
&nbsp;&nbsp;&nbsp; private static LinkedHashMap&lt;RequestKey, Collection&lt;ConfigAttribute&gt;&gt; processMap(<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LinkedHashMap&lt;RequestKey,Collection&lt;ConfigAttribute&gt;&gt; requestMap, ExpressionParser parser) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Assert.notNull(parser, "SecurityExpressionHandler returned a null parser object");<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LinkedHashMap&lt;RequestKey, Collection&lt;ConfigAttribute&gt;&gt; requestToExpressionAttributesMap =<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; new LinkedHashMap&lt;RequestKey, Collection&lt;ConfigAttribute&gt;&gt;(requestMap);<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (Map.Entry&lt;RequestKey, Collection&lt;ConfigAttribute&gt;&gt; entry : requestMap.entrySet()) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RequestKey request = entry.getKey();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Assert.isTrue(entry.getValue().size() == 1, "Expected a single expression attribute for " + request);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ArrayList&lt;ConfigAttribute&gt; attributes = new ArrayList&lt;ConfigAttribute&gt;(1);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String expression = entry.getValue().toArray(new ConfigAttribute[1])[0].getAttribute();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; logger.debug("Adding web access control expression '" + expression + "', for " + request);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //Replacing WebExpressionConfigAttribute with MyWebExpressionConfigAttribute <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //which is defined locally!<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; attributes.add(new MyWebExpressionConfigAttribute(parser.parseExpression(expression)));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } catch (ParseException e) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw new IllegalArgumentException("Failed to parse expression '" + expression + "'");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; requestToExpressionAttributesMap.put(request, attributes);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return requestToExpressionAttributesMap;<br />
&nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp; private static LinkedHashMap&lt;RequestKey,Collection&lt;ConfigAttribute&gt;&gt; initializeFromDb(DataSource datasource,LinkedHashMap&lt;RequestKey, Collection&lt;ConfigAttribute&gt;&gt; configMap){<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; LinkedHashMap&lt;RequestKey,Collection&lt;ConfigAttribute&gt;&gt; result = <br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; new LinkedHashMap&lt;RequestKey, Collection&lt;ConfigAttribute&gt;&gt;();<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Connection conn = null;<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Statement&nbsp; stmt = null;<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ResultSet&nbsp; rs&nbsp;&nbsp; = null;<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; try {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; conn = datasource.getConnection();<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; stmt = conn.createStatement();<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; StringBuilder sql = new StringBuilder("SELECT b.AUTHORITYPATTERN ,'hasRole('||chr(39)||a.ROLENAME||chr(39)||')' rolename ")<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .append(" FROM ROLES a,AUTHORITIES b,ROLE_AUTHS c ")<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .append(" WHERE a.rolename = c.rolename AND b.authorityname = c.authorityname");<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rs = stmt.executeQuery(sql.toString());<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; String roles = "";<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; RequestKey key = null;<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; List&lt;ConfigAttribute&gt; value = null;<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; while(rs != null &amp;&amp; rs.next()){<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; key = new RequestKey(rs.getString(1));<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; roles = rs.getString(2);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; String[] roleArray = roles.split(",|\\s+|;");<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; value = new ArrayList&lt;ConfigAttribute&gt;();<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; for(String role : roleArray){<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ConfigAttribute config = new SecurityConfig(role);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; value.add(config);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; result.put(key, value);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //just for test<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; } catch (SQLException e) {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; e.printStackTrace();<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; } finally{<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; try{<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rs.close();<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; stmt.close();<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; conn.close();<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }catch(SQLException e){<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; e.printStackTrace();<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return result;<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; public boolean supports(Class&lt;?&gt; clazz) {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return FilterInvocation.class.isAssignableFrom(clazz);<br />
&nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp; public DataSource getDatasource() {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return datasource;<br />
&nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp; public void setDatasource(DataSource datasource) {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; this.datasource = datasource;<br />
&nbsp;&nbsp;&nbsp; }<br />
}<br />
&nbsp;(2) expressionHandler:<br />
&nbsp;&nbsp;&nbsp;&nbsp; 这个东西要单独说说，我这里用的是表达式来检测用户角色的，所以，我用org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler来处理了，还有其他的方式，就是直接用角色进行判断，那样会更好，这里就不描述了！<br />
<br />
<br />
<img src ="http://www.blogjava.net/taochen1984/aggbug/310744.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/taochen1984/" target="_blank">taochen</a> 2010-01-25 16:29 <a href="http://www.blogjava.net/taochen1984/articles/310744.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>SpringSecurity使用记录（六）-- 本地配置一</title><link>http://www.blogjava.net/taochen1984/articles/310221.html</link><dc:creator>taochen</dc:creator><author>taochen</author><pubDate>Mon, 25 Jan 2010 07:56:00 GMT</pubDate><guid>http://www.blogjava.net/taochen1984/articles/310221.html</guid><wfw:comment>http://www.blogjava.net/taochen1984/comments/310221.html</wfw:comment><comments>http://www.blogjava.net/taochen1984/articles/310221.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/taochen1984/comments/commentRss/310221.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/taochen1984/services/trackbacks/310221.html</trackback:ping><description><![CDATA[按照SpringSecurity的文档，我们可以使用namespace的配置方式（前篇中已经说明）。<br />
但是，我们这里的需求有点蹊跷，就是通过spring context进行权限配置太不方便，你想想能让人家客户通过spring xml来配置权限吗？不能，坚决不能！所以，我就单步跟踪获取里面的东西（这种方法比直接看代码快点，而且可以知道里面的逻辑结构！）<br />
那就开始吧：<br />
1.配置FilterChainProxy：<br />
&nbsp; SpringSecurity的验证过程是通过一系列的filter来实现的。<br />
&nbsp; 这种chain的设计模式比较经典，可以说相当经典！<br />
&nbsp; 看看代码实现：<br />
&nbsp; 上篇中说过，默认的配置要求&lt;filter-name&gt;springSecurityFilterChain&lt;/filter-name&gt;，那这个springSecurityFilterChain是怎么来用的呢？<br />
&nbsp; public class DelegatingFilterProxy extends GenericFilterBean {<br />
&nbsp; ... ... ...<br />
&nbsp; protected void initFilterBean() throws ServletException {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // If no target bean name specified, use filter name.<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (this.targetBeanName == null) {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; this.targetBeanName = getFilterName();<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // Fetch Spring root application context and initialize the delegate early,<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // if possible. If the root application context will be started after this<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // filter proxy, we'll have to resort to lazy initialization.<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; synchronized (this.delegateMonitor) {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; WebApplicationContext wac = findWebApplicationContext();<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (wac != null) {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; this.delegate = initDelegate(wac);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp; .....<br />
&nbsp; }<br />
&nbsp; 不用说，你会猜到我们没有配置过targetBeanName这个属性，所以，就有了this.targetBeanName = getFilterName();这样的话就会配置FilterChainProxy了，因为FilterChainProxy在springContext中id是springSecurityFilterChain，所以我们要通过自己的数据库方式配置的话，就要琢磨这个FilterChainProxy了！<br />
&nbsp; 所以，首先做点这样的配置吧：<br />
&nbsp; &lt;beans:bean id="myFilterChain" class="org.springframework.security.web.FilterChainProxy" &gt;<br />
&nbsp; &nbsp;&nbsp;&nbsp; &lt;filter-chain-map path-type="ant"&gt;<br />
&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;filter-chain pattern="/login.jsp*" filters="none"/&gt;<br />
&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;filter-chain pattern="/**" filters="securityContextPersistenceFilter,<br />
&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; logoutFilter,<br />
&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; myUsernamePasswordAuthenticationFilter,<br />
&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; basicAuthenticationFilter,<br />
&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; requestCacheAwareFilter,<br />
&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; securityContextHolderAwareRequestFilter,<br />
&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; anonymousAuthenticationFilter,<br />
&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sessionManagementFilter,<br />
&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; exceptionTranslationFilter,<br />
&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; filterSecurityInterceptor"/&gt;<br />
&nbsp; &nbsp;&nbsp;&nbsp; &lt;/filter-chain-map&gt;<br />
&nbsp; &lt;/beans:bean&gt;<br />
这个里面配置的id为myFilterChain，所以要在web.xml里面做相应配置：<br />
&nbsp;&nbsp; &lt;filter&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;filter-name&gt;myFilterChain&lt;/filter-name&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;filter-class&gt;org.springframework.web.filter.DelegatingFilterProxy&lt;/filter-class&gt;<br />
&nbsp; &lt;/filter&gt;<br />
&nbsp; &lt;filter-mapping&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;filter-name&gt;myFilterChain&lt;/filter-name&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;url-pattern&gt;/*&lt;/url-pattern&gt;<br />
&nbsp; &lt;/filter-mapping&gt;<br />
而且，尤为重要的是要配置上这些过滤器：<br />
filter-chain pattern="/**" filters="securityContextPersistenceFilter,logoutFilter,<br />
&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; myUsernamePasswordAuthenticationFilter,<br />
&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; basicAuthenticationFilter,<br />
&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; requestCacheAwareFilter,<br />
&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; securityContextHolderAwareRequestFilter,<br />
&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; anonymousAuthenticationFilter,<br />
&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sessionManagementFilter,<br />
&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; exceptionTranslationFilter,<br />
&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; filterSecurityInterceptor"<br />
针对这些过滤器的用途，在spring security的文档中有详细描述，这里不多说了，在文档中的具体位置是7.2 FilterChainProxy，看看这一章就会有感觉了，不过绝知此事要躬行啊！<br />
完成这些配置之后，我们就算是把入口给搭建好了！<br />
鉴于文档篇幅，换到下篇接着说。<br />
<br />
<img src ="http://www.blogjava.net/taochen1984/aggbug/310221.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/taochen1984/" target="_blank">taochen</a> 2010-01-25 15:56 <a href="http://www.blogjava.net/taochen1984/articles/310221.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>SpringSecurity使用记录（五）-- 配置</title><link>http://www.blogjava.net/taochen1984/articles/310072.html</link><dc:creator>taochen</dc:creator><author>taochen</author><pubDate>Tue, 19 Jan 2010 06:19:00 GMT</pubDate><guid>http://www.blogjava.net/taochen1984/articles/310072.html</guid><wfw:comment>http://www.blogjava.net/taochen1984/comments/310072.html</wfw:comment><comments>http://www.blogjava.net/taochen1984/articles/310072.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/taochen1984/comments/commentRss/310072.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/taochen1984/services/trackbacks/310072.html</trackback:ping><description><![CDATA[研究了好长时间，不知道从哪里下手。新的版本，很多东西在网上找不到，只能看他们的文档，当然这些文档相当不错，就看是否耐心的研究了！总是有急躁的心理作祟，不能专心研读，却处处碰壁，效率上反而未达预期效果！<br />
终于，在无数次的沮丧下，稍微看到了点光亮！前面的文章太过皮毛，接下来的一些，希望能更加实际的，更加深入的分析每一个过程！<br />
<br />
一直通过默认配置进行设置：<br />
namespace(是security 3.0,网上也看到一些兄弟描述的是3.0，但是总是不符合我这里的namespace配置):<br />
&lt;beans:beans xmlns="http://www.springframework.org/schema/security"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; xmlns:beans="http://www.springframework.org/schema/beans"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; xsi:schemaLocation="http://www.springframework.org/schema/beans<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; http://www.springframework.org/schema/beans/spring-beans-3.0.xsd<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; http://www.springframework.org/schema/security <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; http://www.springframework.org/schema/security/spring-security-3.0.xsd"&gt;<br />
按照默认配置的http（这是用来根据namespace设置的基本的security过滤器chain）：<br />
auto-config=true时，就相当于<br />
&nbsp; &lt;http&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;form-login /&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;http-basic /&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;logout /&gt;<br />
&nbsp; &lt;/http&gt;<br />
也就是使用了默认的过滤器。<br />
我最开始的想法是能够把本地的login信息（不是调用spring security的login方法），传入到spring security的验证过滤器里面。<br />
这里有一个比较关键的问题，就是封装他们的过滤器（或者仅仅是知道他们到底是哪些过滤器在起作用）：<br />
表1
<table summary="Standard Filter
    Aliases and Ordering" style="border: 0.5pt solid ; border-collapse: collapse;" width="938" height="337">
    <tbody>
        <tr>
            <td align="left">
            <table summary="Standard Filter
                Aliases and Ordering" style="border: 0.5pt solid ; border-collapse: collapse;">
                <thead>
                    <tr>
                        <th align="center">Alias</th><th align="center">Filter Class</th><th align="center">Namespace Element or
                        Attribute</th>
                    </tr>
                </thead>
                <tbody>
                    <tr>
                        <td align="left">
                        CHANNEL_FILTER</td>
                        <td align="left"><code class="literal">ChannelProcessingFilter</code></td>
                        <td align="left"><code class="literal">http/intercept-url@requires-channel</code></td>
                    </tr>
                    <tr>
                        <td align="left">
                        CONCURRENT_SESSION_FILTER</td>
                        <td align="left"><code class="literal">ConcurrentSessionFilter</code>
                        </td>
                        <td align="left"><code class="literal">session-management/concurrency-control</code></td>
                    </tr>
                    <tr>
                        <td align="left">
                        SECURITY_CONTEXT_FILTER</td>
                        <td align="left"><code class="classname">SecurityContextPersistenceFilter</code></td>
                        <td align="left"><code class="literal">http</code></td>
                    </tr>
                    <tr>
                        <td align="left">
                        LOGOUT_FILTER
                        </td>
                        <td align="left"><code class="literal">LogoutFilter</code></td>
                        <td align="left"><code class="literal">http/logout</code></td>
                    </tr>
                    <tr>
                        <td align="left">
                        X509_FILTER
                        </td>
                        <td align="left"><code class="literal">X509AuthenticationFilter</code></td>
                        <td align="left"><code class="literal">http/x509</code></td>
                    </tr>
                    <tr>
                        <td align="left">
                        PRE_AUTH_FILTER
                        </td>
                        <td align="left"><code class="literal">AstractPreAuthenticatedProcessingFilter</code>
                        Subclasses</td>
                        <td align="left">N/A</td>
                    </tr>
                    <tr>
                        <td align="left"> CAS_FILTER
                        </td>
                        <td align="left"><code class="literal">CasAuthenticationFilter</code></td>
                        <td align="left">N/A</td>
                    </tr>
                    <tr>
                        <td align="left">
                        FORM_LOGIN_FILTER
                        </td>
                        <td align="left"><code class="literal">UsernamePasswordAuthenticationFilter</code></td>
                        <td align="left"><code class="literal">http/form-login</code></td>
                    </tr>
                    <tr>
                        <td align="left">
                        BASIC_AUTH_FILTER
                        </td>
                        <td align="left"><code class="literal">BasicAuthenticationFilter</code></td>
                        <td align="left"><code class="literal">http/http-basic</code></td>
                    </tr>
                    <tr>
                        <td align="left">
                        SERVLET_API_SUPPORT_FILTER</td>
                        <td align="left"><code class="literal">SecurityContextHolderAwareFilter</code></td>
                        <td align="left"><code class="literal">http/@servlet-api-provision</code></td>
                    </tr>
                    <tr>
                        <td align="left">
                        REMEMBER_ME_FILTER
                        </td>
                        <td align="left"><code class="classname">RememberMeAuthenticationFilter</code></td>
                        <td align="left"><code class="literal">http/remember-me</code></td>
                    </tr>
                    <tr>
                        <td align="left">
                        ANONYMOUS_FILTER
                        </td>
                        <td align="left"><code class="literal">AnonymousAuthenticationFilter</code></td>
                        <td align="left"><code class="literal">http/anonymous</code></td>
                    </tr>
                    <tr>
                        <td align="left">
                        SESSION_MANAGEMENT_FILTER</td>
                        <td align="left"><code class="literal">SessionManagementFilter</code></td>
                        <td align="left"><code class="literal">session-management</code></td>
                    </tr>
                    <tr>
                        <td align="left">EXCEPTION_TRANSLATION_FILTER
                        </td>
                        <td align="left"><code class="classname">ExceptionTranslationFilter</code></td>
                        <td align="left"><code class="literal">http</code></td>
                    </tr>
                    <tr>
                        <td align="left">
                        FILTER_SECURITY_INTERCEPTOR
                        </td>
                        <td align="left"><code class="classname">FilterSecurityInterceptor</code></td>
                        <td align="left"><code class="literal">http</code></td>
                    </tr>
                    <tr>
                        <td align="left">
                        SWITCH_USER_FILTER
                        </td>
                        <td align="left"><code class="literal">SwitchUserFilter</code></td>
                        <td align="left">N/A</td>
                    </tr>
                </tbody>
            </table>
            </td>
            <td align="left"><br />
            </td>
            <td align="left"><br />
            </td>
        </tr>
    </tbody>
</table>
（最开始看的时候，把这个表格忽略了，现在看来这些就是我们想要的！）<br />
我们的验证过程，就是按照这样的顺序进行的。自上而下进行。<br />
<br />
如果我们要自己定制相应的验证处理方法（在过滤器里面），我们就可以对照上面的过滤器，覆盖相应的接口方法。<br />
根据我的处理过程，主要是用户名密码的验证过程，我大体描述一下自己的配置和处理过程：<br />
1.配置namespace的标签:<br />
&nbsp; &lt;http&nbsp; use-expressions="true" &gt;&lt;!-- This is not the default value --&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;custom-filter position="FORM_LOGIN_FILTER" ref="myFilter"/&gt; &lt;!--This is my own filter which just extends AbstractAuthenticationProcessingFilter as what UsernamePasswordAuthenticationFilter does.--&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;intercept-url pattern="/test/**"&nbsp; access="hasRole('ROLE_MY')"/&gt;&lt;!-- I tested that what is role,and how I can use it.So ROLE_MY is just a role name I defined.--&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;intercept-url pattern="/login.jsp*" access="permitAll" /&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;logout /&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;anonymous /&gt; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;http-basic /&gt;<br />
&nbsp; &lt;/http&gt;<br />
这里的问题是，要定制自己的过滤器，就要通过&lt;custom-filter/&gt;，然后对照 表1 中指定的position,覆盖默认的filter。<br />
2.我的form-login&nbsp; filter配置（这些配置都是在application-security.xml文件中）为：<br />
&lt;beans:bean id="myFilter" <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class="com.saveworld.authentication.filters.MyUsernamePasswordAuthenticationFilter"&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;beans:property name="defaultTargetUrl"&nbsp; value="/default.jsp" /&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;beans:property name="defaultFailureUrl"&nbsp; value="/error.jsp" /&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;beans:property name="authenticationManager" ref="authenticationManager" /&gt; <br />
&nbsp;&nbsp;&nbsp; &lt;beans:property name="filterProcessesUrl" value="/j_spring_security_check" /&gt; <br />
&nbsp;&nbsp;&nbsp; &lt;beans:property name="continueChainBeforeSuccessfulAuthentication" value="false" /&gt; <br />
&nbsp; &lt;/beans:bean&gt;<br />
<br />
NOTE：<br />
在这里有个问题就是： filter position conflicts!<br />
如果使用这样的配置<br />
&lt;http auto-config='true'&gt;<br />
&nbsp;&nbsp; &lt;custom-filter position="FORM_LOGIN_FILTER" ref="myFilter"/&gt;<br />
&lt;/http&gt;<br />
自定义的filter对应的position是FORM_LOGIN_FILTER<br />
但是因为使用了auto-config='true'，所以默认有&lt;form-login /&gt;，which is on the position FORM_LOGIN_FILTER!<br />
这时就会出现position conflicts问题了。当然，如果你没有设置auto-config='true'，但是却自己设置了&lt;form-login /&gt;，呵呵，这个情况就是自己大意了，还是有了position conflicts的异常，所以，好好看看上面的表格是相当必要的，看清楚每个position默认都对应那些namespace，都是对应的哪些filter！<br />
<br />
接着：<br />
我的类MyUsernamePasswordAuthenticationFilter实现（我的说明方式就按照哪里需要，哪里加入的方式了）：<br />
package com.saveworld.authentication.filters;<br />
<br />
import java.io.IOException;<br />
<br />
import javax.servlet.ServletException;<br />
import javax.servlet.http.HttpServletRequest;<br />
import javax.servlet.http.HttpServletResponse;<br />
import javax.servlet.http.HttpSession;<br />
<br />
import org.springframework.security.authentication.AuthenticationServiceException;<br />
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;<br />
import org.springframework.security.authentication.event.InteractiveAuthenticationSuccessEvent;<br />
import org.springframework.security.core.Authentication;<br />
import org.springframework.security.core.AuthenticationException;<br />
import org.springframework.security.core.context.SecurityContextHolder;<br />
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;<br />
import org.springframework.security.web.authentication.AuthenticationFailureHandler;<br />
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;<br />
import org.springframework.security.web.authentication.NullRememberMeServices;<br />
import org.springframework.security.web.authentication.RememberMeServices;<br />
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;<br />
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;<br />
import org.springframework.security.web.util.TextEscapeUtils;<br />
import org.springframework.util.Assert;<br />
<br />
import com.saveworld.authentication.handlers.MySavedRequestAwareAuthenticationSuccessHandler;<br />
import com.saveworld.authentication.handlers.MySimpleUrlAuthenticationFailureHandler;<br />
<br />
public class MyUsernamePasswordAuthenticationFilter extends AbstractAuthenticationProcessingFilter{<br />
&nbsp;&nbsp;&nbsp; //~ Static fields/initializers =====================================================================================<br />
<br />
&nbsp;&nbsp;&nbsp; public static final String SPRING_SECURITY_FORM_USERNAME_KEY = "username";<br />
&nbsp;&nbsp;&nbsp; public static final String SPRING_SECURITY_FORM_PASSWORD_KEY = "password";<br />
&nbsp;&nbsp;&nbsp; public static final String SPRING_SECURITY_LAST_USERNAME_KEY = "SPRING_SECURITY_LAST_USERNAME";<br />
<br />
&nbsp;&nbsp;&nbsp; private String usernameParameter = SPRING_SECURITY_FORM_USERNAME_KEY;<br />
&nbsp;&nbsp;&nbsp; private String passwordParameter = SPRING_SECURITY_FORM_PASSWORD_KEY;<br />
&nbsp;&nbsp;&nbsp; private boolean postOnly = true;<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; private boolean allowSessionCreation = true;<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; private String defaultTargetUrl = "/";<br />
&nbsp;&nbsp;&nbsp; private String defaultFailureUrl = "/login.jsp";<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; private AuthenticationSuccessHandler successHandler = null;<br />
&nbsp;&nbsp;&nbsp; private AuthenticationFailureHandler failureHandler = null;<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; private RememberMeServices rememberMeServices = null;<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; //~ Constructors ===================================================================================================<br />
<br />
&nbsp;&nbsp;&nbsp; public MyUsernamePasswordAuthenticationFilter() {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //初始化<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; super("/j_spring_security_check");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.rememberMeServices = (super.getRememberMeServices() == null) <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;? new NullRememberMeServices():super.getRememberMeServices();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp; //~ Methods ========================================================================================================<br />
<br />
&nbsp;&nbsp;&nbsp; public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (postOnly &amp;&amp; !request.getMethod().equals("POST")) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String username = obtainUsername(request);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String password = obtainPassword(request);<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (username == null) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; username = "";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (password == null) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; password = "";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; username = username.trim();<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Place the last username attempted into HttpSession for views<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HttpSession session = request.getSession(false);<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (session != null || getAllowSessionCreation()) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; request.getSession().setAttribute(SPRING_SECURITY_LAST_USERNAME_KEY, TextEscapeUtils.escapeEntities(username));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Allow subclasses to set the "details" property<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; setDetails(request, authRequest);<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return this.getAuthenticationManager().authenticate(authRequest);<br />
&nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; public void successfulAuthentication(HttpServletRequest request, HttpServletResponse response,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Authentication authResult) throws IOException, ServletException {<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (logger.isDebugEnabled()) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; logger.debug("Authentication success. Updating SecurityContextHolder to contain: " + authResult);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SecurityContextHolder.getContext().setAuthentication(authResult);<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rememberMeServices.loginSuccess(request, response, authResult);<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Fire event<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (this.eventPublisher != null) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; eventPublisher.publishEvent(new InteractiveAuthenticationSuccessEvent(authResult, this.getClass()));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(successHandler == null){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; successHandler = new MySavedRequestAwareAuthenticationSuccessHandler(getDefaultTargetUrl());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; successHandler.onAuthenticationSuccess(request, response, authResult);<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; public void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; AuthenticationException failed) throws IOException, ServletException {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SecurityContextHolder.clearContext();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(failureHandler == null){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; failureHandler = new MySimpleUrlAuthenticationFailureHandler(getDefaultFailureUrl());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (logger.isDebugEnabled()) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; logger.debug("Authentication request failed: " + failed.toString());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; logger.debug("Updated SecurityContextHolder to contain null Authentication");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; logger.debug("Delegating to authentication failure handler" + failureHandler);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HttpSession session = request.getSession(false);<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (session != null || allowSessionCreation) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; request.getSession().setAttribute(SPRING_SECURITY_LAST_EXCEPTION_KEY, failed);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rememberMeServices.loginFail(request, response);<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; failureHandler.onAuthenticationFailure(request, response, failed);<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; /**<br />
&nbsp;&nbsp;&nbsp;&nbsp; * Enables subclasses to override the composition of the password, such as by including additional values<br />
&nbsp;&nbsp;&nbsp;&nbsp; * and a separator.&lt;p&gt;This might be used for example if a postcode/zipcode was required in addition to the<br />
&nbsp;&nbsp;&nbsp;&nbsp; * password. A delimiter such as a pipe (|) should be used to separate the password and extended value(s). The<br />
&nbsp;&nbsp;&nbsp;&nbsp; * &lt;code&gt;AuthenticationDao&lt;/code&gt; will need to generate the expected password in a corresponding manner.&lt;/p&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; *<br />
&nbsp;&nbsp;&nbsp;&nbsp; * @param request so that request attributes can be retrieved<br />
&nbsp;&nbsp;&nbsp;&nbsp; *<br />
&nbsp;&nbsp;&nbsp;&nbsp; * @return the password that will be presented in the &lt;code&gt;Authentication&lt;/code&gt; request token to the<br />
&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;code&gt;AuthenticationManager&lt;/code&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; */<br />
&nbsp;&nbsp;&nbsp; protected String obtainPassword(HttpServletRequest request) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return request.getParameter(passwordParameter);<br />
&nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp; /**<br />
&nbsp;&nbsp;&nbsp;&nbsp; * Enables subclasses to override the composition of the username, such as by including additional values<br />
&nbsp;&nbsp;&nbsp;&nbsp; * and a separator.<br />
&nbsp;&nbsp;&nbsp;&nbsp; *<br />
&nbsp;&nbsp;&nbsp;&nbsp; * @param request so that request attributes can be retrieved<br />
&nbsp;&nbsp;&nbsp;&nbsp; *<br />
&nbsp;&nbsp;&nbsp;&nbsp; * @return the username that will be presented in the &lt;code&gt;Authentication&lt;/code&gt; request token to the<br />
&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;code&gt;AuthenticationManager&lt;/code&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; */<br />
&nbsp;&nbsp;&nbsp; protected String obtainUsername(HttpServletRequest request) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return request.getParameter(usernameParameter);<br />
&nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp; /**<br />
&nbsp;&nbsp;&nbsp;&nbsp; * Provided so that subclasses may configure what is put into the authentication request's details<br />
&nbsp;&nbsp;&nbsp;&nbsp; * property.<br />
&nbsp;&nbsp;&nbsp;&nbsp; *<br />
&nbsp;&nbsp;&nbsp;&nbsp; * @param request that an authentication request is being created for<br />
&nbsp;&nbsp;&nbsp;&nbsp; * @param authRequest the authentication request object that should have its details set<br />
&nbsp;&nbsp;&nbsp;&nbsp; */<br />
&nbsp;&nbsp;&nbsp; protected void setDetails(HttpServletRequest request, UsernamePasswordAuthenticationToken authRequest) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; authRequest.setDetails(authenticationDetailsSource.buildDetails(request));<br />
&nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp; /**<br />
&nbsp;&nbsp;&nbsp;&nbsp; * Sets the parameter name which will be used to obtain the username from the login request.<br />
&nbsp;&nbsp;&nbsp;&nbsp; *<br />
&nbsp;&nbsp;&nbsp;&nbsp; * @param usernameParameter the parameter name. Defaults to "j_username".<br />
&nbsp;&nbsp;&nbsp;&nbsp; */<br />
&nbsp;&nbsp;&nbsp; public void setUsernameParameter(String usernameParameter) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Assert.hasText(usernameParameter, "Username parameter must not be empty or null");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.usernameParameter = usernameParameter;<br />
&nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp; /**<br />
&nbsp;&nbsp;&nbsp;&nbsp; * Sets the parameter name which will be used to obtain the password from the login request..<br />
&nbsp;&nbsp;&nbsp;&nbsp; *<br />
&nbsp;&nbsp;&nbsp;&nbsp; * @param passwordParameter the parameter name. Defaults to "j_password".<br />
&nbsp;&nbsp;&nbsp;&nbsp; */<br />
&nbsp;&nbsp;&nbsp; public void setPasswordParameter(String passwordParameter) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Assert.hasText(passwordParameter, "Password parameter must not be empty or null");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.passwordParameter = passwordParameter;<br />
&nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp; /**<br />
&nbsp;&nbsp;&nbsp;&nbsp; * Defines whether only HTTP POST requests will be allowed by this filter.<br />
&nbsp;&nbsp;&nbsp;&nbsp; * If set to true, and an authentication request is received which is not a POST request, an exception will<br />
&nbsp;&nbsp;&nbsp;&nbsp; * be raised immediately and authentication will not be attempted. The &lt;tt&gt;unsuccessfulAuthentication()&lt;/tt&gt; method<br />
&nbsp;&nbsp;&nbsp;&nbsp; * will be called as if handling a failed authentication.<br />
&nbsp;&nbsp;&nbsp;&nbsp; * &lt;p&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; * Defaults to &lt;tt&gt;true&lt;/tt&gt; but may be overridden by subclasses.<br />
&nbsp;&nbsp;&nbsp;&nbsp; */<br />
&nbsp;&nbsp;&nbsp; public void setPostOnly(boolean postOnly) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.postOnly = postOnly;<br />
&nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp; public final String getUsernameParameter() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return usernameParameter;<br />
&nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp; public final String getPasswordParameter() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return passwordParameter;<br />
&nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp; public String getDefaultTargetUrl() {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return defaultTargetUrl;<br />
&nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp; public void setDefaultTargetUrl(String defaultTargetUrl) {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; this.defaultTargetUrl = defaultTargetUrl;<br />
&nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp; public String getDefaultFailureUrl() {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return defaultFailureUrl;<br />
&nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp; public void setDefaultFailureUrl(String defaultFailureUrl) {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; this.defaultFailureUrl = defaultFailureUrl;<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; <br />
}<br />
<br />
这里要关注的就是几个字段：<br />
&nbsp;&nbsp;&nbsp; &lt;beans:property name="defaultTargetUrl"&nbsp; value="/default.jsp" /&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;beans:property name="defaultFailureUrl"&nbsp; value="/error.jsp" /&gt;<br />
这两个字段是指定验证成功或失败后转向的页面，这里要注意是以&#8220;/&#8221;开头，否则在AbstractAuthenticationTargetUrlRequestHandler中调用setDefaultTargetUrl方法时会抛出"defaultTarget must start with '/' or with 'http(s)'"的异常！<br />
默认情况下，FORM_LOGIN_FILTER对应的target url和failure url都是通过 &lt;form-login /&gt;中的<strong>default-target-url,</strong><strong>authentication-failure-url指定，也可以通过指定</strong><strong>authentication-success-handler-ref和</strong><strong>authentication-failure-handler-ref来实现认证成功和失败之后的处理方式.在我的filter中，是自定义了两个handler分别对应成功的和失败的验证。<br />
<br />
</strong>3.用户信息获取和验证：<br />
&nbsp; &lt;authentication-manager alias="authenticationManager"&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;authentication-provider user-service-ref='myUserDetailsService'/&gt;<br />
&nbsp; &lt;/authentication-manager&gt;<br />
&nbsp; &lt;beans:bean id="myUserDetailsService" class="com.saveworld.userdetails.MyUserDetailsService"&gt;&lt;/beans:bean&gt; <br />
这个指定的authentication-manager是使用默认的ProviderManager，这个manager是在哪里使用的呢？<br />
看看MyUsernamePasswordAuthenticationFilter中的attemptAuthentication方法的最后一行，这里是获取指定的authentication-manager。getAuthenticationManager是从父类AbstractAuthenticationProcessingFilter继承过来的。所以，我们的&lt;authentication-manager alias="authenticationManager"&gt;中就指定了一个别名authenticationManager，在myfilter中设置属性的引用&lt;beans:property name="authenticationManager" ref="authenticationManager" /&gt;，然后我们就可以通过Provider引用我们自己的用户信息验证service了（eg:用户信息获取和验证）！这里实际是使用了Method Template模式（AbstractAuthenticationManager中设定模板函数doAuthentication，ProviderManager中做了实现）。<br />
这里难免要说明一下，我们的Service是如何被调用的，我们做了配置&lt;authentication-provider user-service-ref='myUserDetailsService'/&gt;<br />
指定了我们的UserDetailsService，类实现(为了测试和理解，The easier the better!)：<br />
package com.saveworld.userdetails;<br />
<br />
import java.util.ArrayList;<br />
import java.util.HashMap;<br />
import java.util.List;<br />
<br />
import org.springframework.dao.DataAccessException;<br />
import org.springframework.security.core.GrantedAuthority;<br />
import org.springframework.security.core.authority.GrantedAuthorityImpl;<br />
import org.springframework.security.core.userdetails.User;<br />
import org.springframework.security.core.userdetails.UserDetails;<br />
import org.springframework.security.core.userdetails.UserDetailsService;<br />
import org.springframework.security.core.userdetails.UsernameNotFoundException;<br />
<br />
public class MyUserDetailsService implements UserDetailsService{<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; private HashMap&lt;String, User&gt; userDetails = new HashMap&lt;String, User&gt;();<br />
&nbsp;&nbsp;&nbsp; private HashMap&lt;String, List&lt;GrantedAuthority&gt;&gt; userAuthorities = new HashMap&lt;String, List&lt;GrantedAuthority&gt;&gt;(); <br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; public MyUserDetailsService(){<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //Make up a user named 'rod' with 'rod' as his password!<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; String username = "rod";<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; String password = "1";<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; boolean enabled = true;<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //purview for rod<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; GrantedAuthority specAuth = new GrantedAuthorityImpl("ROLE_MY");<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; List&lt;GrantedAuthority&gt; rodsAuthsList = new ArrayList&lt;GrantedAuthority&gt;();<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rodsAuthsList.add(specAuth);<br />
//&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; userAuthorities.put("rod", rodsAuthsList);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; userDetails.put("rod", new User(username, password, enabled, true, true, true, rodsAuthsList));<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; public UserDetails loadUserByUsername(String username)<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; throws UsernameNotFoundException, DataAccessException {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; System.out.println("验证从此地过了一遭");<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return userDetails.get(username);<br />
&nbsp;&nbsp;&nbsp; }<br />
<br />
}<br />
通过DaoAuthenticationProvider中的userDetailsService关联我们的UserDetailsService（不得不提的是，AbstractUserDetailsAuthenticationProvider中有设定了模板函数retrieveUser，DaoAuthenticationProvider进行了实现，通过retrieveUser方法调用UserDetailsService.loadUserByUsername，然后在AbstractUserDetailsAuthenticationProvider.authenticate方法进行验证）。<br />
接下来就是看验证的结果了，是否成功，进入filter chain中。<br />
这一切就这么有条不紊的进行了！呵呵，总算是有点成果了！有了一点点感性的认识了！上面的描述中难免会有些混乱，但是尽量是哪里需要，哪里就做说明！<br />
<br />
下篇中说明entrypoint的用处吧！<br />
<img src ="http://www.blogjava.net/taochen1984/aggbug/310072.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/taochen1984/" target="_blank">taochen</a> 2010-01-19 14:19 <a href="http://www.blogjava.net/taochen1984/articles/310072.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>SpringSecurity使用记录（二）--核心分析篇</title><link>http://www.blogjava.net/taochen1984/articles/307275.html</link><dc:creator>taochen</dc:creator><author>taochen</author><pubDate>Fri, 25 Dec 2009 07:53:00 GMT</pubDate><guid>http://www.blogjava.net/taochen1984/articles/307275.html</guid><wfw:comment>http://www.blogjava.net/taochen1984/comments/307275.html</wfw:comment><comments>http://www.blogjava.net/taochen1984/articles/307275.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/taochen1984/comments/commentRss/307275.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/taochen1984/services/trackbacks/307275.html</trackback:ping><description><![CDATA[不得不再感叹一下，策略模式在SpringSecurity中用的地方太多了！<br />
<br />
? SecurityContextHolder, to provide access to the SecurityContext.<br />
? SecurityContext,&nbsp; to&nbsp; hold&nbsp; the&nbsp; Authentication&nbsp; and&nbsp; possibly&nbsp; request-specific&nbsp; security<br />
information.<br />
? Authentication, to represent the principal in a Spring Security-specific manner.<br />
? GrantedAuthority, to reflect the application-wide permissions granted to a principal.<br />
? UserDetails, to provide the necessary information to build an Authentication object from your<br />
application's DAOs or other source source of security data.<br />
? UserDetailsService, to create a UserDetails when passed in a String-based username<br />
(or certificate ID or the like).<br />
（以上是从文档里面抄出来的！）<br />
这就是权限的核心了！！（持续修改中。。。。。。）<br />
<img src ="http://www.blogjava.net/taochen1984/aggbug/307275.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/taochen1984/" target="_blank">taochen</a> 2009-12-25 15:53 <a href="http://www.blogjava.net/taochen1984/articles/307275.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>SpringSecurity使用记录（一）</title><link>http://www.blogjava.net/taochen1984/articles/307203.html</link><dc:creator>taochen</dc:creator><author>taochen</author><pubDate>Thu, 24 Dec 2009 12:05:00 GMT</pubDate><guid>http://www.blogjava.net/taochen1984/articles/307203.html</guid><wfw:comment>http://www.blogjava.net/taochen1984/comments/307203.html</wfw:comment><comments>http://www.blogjava.net/taochen1984/articles/307203.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/taochen1984/comments/commentRss/307203.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/taochen1984/services/trackbacks/307203.html</trackback:ping><description><![CDATA[第一次配置和使用SpringSecurity，总是要碰很多次墙！<br />
先说说个人理解的它里面比较有意义的架构。<br />
里面有好多设计模式的影子：策略模式，代理模式，工厂模式，链条模式=====，看到这些模式（除了工厂或单例）心里总是会有些兴奋，总算是看到了模式的真正练兵场！跟兄弟们好好分享一下!(才看了一天！有不对之处，还望各位斧正！)<br />
策略模式（Strategy Pattern）:<br />
主要说一下session相关的这个策略模式，以SessionAuthenticationStrategy接口的策略划分，根据我们的session安全策略，指定不同的策略，现在看是这种布局：<br />
<table border="0" cellpadding="2" cellspacing="2" width="853" height="280">
    <tbody>
        <tr>
            <td>&nbsp;顶层接口</td>
            <td>&nbsp;SessionAuthenticationStrategy</td>
            <td>&nbsp;</td>
            <td>&nbsp;</td>
        </tr>
        <tr>
            <td>&nbsp;具体实现</td>
            <td>&nbsp;SessionFixationProtectionStrategy<br />
            （直接默认实现）</td>
            <td>&nbsp;NullAuthenticatedSessionStrategy<br />
            （空实现）<br />
            </td>
            <td>&nbsp;</td>
        </tr>
        <tr>
            <td>&nbsp;二级实现</td>
            <td>&nbsp;ConcurrentSessionControlStrategy</td>
            <td>&nbsp;</td>
            <td>&nbsp;</td>
        </tr>
    </tbody>
</table>
<br />
画图比较麻烦，各位还是凑合着看吧！说明一下：顶层接口被下面&#8220;具体实现&#8221;两个类实现，而&#8220;二级实现&#8221;实现SessionFixationProtectionStrategy。具体采用哪种策略要看我们的配置了！<br />
代理模式（Proxy）：<br />
很明显的代理类，DelegatingFilterProxy和FilterChainProxy，这两个类看着心里都痒痒的，呵呵，平常总是看代理模式呀什么的，即时看着例子也不踏实，现在看到这两个东西，心里突然有种平静的激动！<br />
这两个代理类以FilterChainProxy为例说明一下吧，FilterChainProxy代理了权限验证Filters的工作，通过它来访问整个过滤器串里面的过滤器。<br />
Chain模式：这个也应该以FilterChainProxy这个类入口来分析，呵呵，有兴趣的各位就通过这个来看看吧！<br />
<img src ="http://www.blogjava.net/taochen1984/aggbug/307203.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/taochen1984/" target="_blank">taochen</a> 2009-12-24 20:05 <a href="http://www.blogjava.net/taochen1984/articles/307203.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>