??xml version="1.0" encoding="utf-8" standalone="yes"?>色噜噜色狠狠狠狠狠综合色一,国产一区二区三区久久久,亚洲二区avhttp://www.aygfsteel.com/taochen1984/category/42649.htmlzh-cnWed, 27 Jan 2010 08:36:19 GMTWed, 27 Jan 2010 08:36:19 GMT60SpringSecurity使用记录Q六Q?- 本地配置?/title><link>http://www.aygfsteel.com/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.aygfsteel.com/taochen1984/articles/310744.html</guid><wfw:comment>http://www.aygfsteel.com/taochen1984/comments/310744.html</wfw:comment><comments>http://www.aygfsteel.com/taochen1984/articles/310744.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/taochen1984/comments/commentRss/310744.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/taochen1984/services/trackbacks/310744.html</trackback:ping><description><![CDATA[接着来?br /> 2.qo(h)器的配置Q?br />   我们已经配置?jin)那些过滤器了(jin),但是要跟spring context中的对象对应Q于是乎Q做?jin)如下配|:(x)<br />   <beans:bean id="securityContextPersistenceFilter" <br />           class="org.springframework.security.web.context.SecurityContextPersistenceFilter"><br />   </beans:bean><br />   <beans:bean id="logoutFilter" <br />           class="org.springframework.security.web.authentication.logout.LogoutFilter" ><br />           <beans:constructor-arg type="java.lang.String" value="/"/><br />           <beans:constructor-arg ref="securityContextLogoutHandler"/><br />   </beans:bean><br />   <beans:bean id="basicAuthenticationFilter" <br />           class="org.springframework.security.web.authentication.www.BasicAuthenticationFilter"><br />           <beans:property name="authenticationManager" ref="authenticationManager"></beans:property><br />           <beans:property name="authenticationEntryPoint" ref="authenticationProcessingFilterEntryPoint"></beans:property><br />   </beans:bean><br />   <beans:bean id="requestCacheAwareFilter" <br />           class="org.springframework.security.web.savedrequest.RequestCacheAwareFilter"><br />   </beans:bean><br />   <beans:bean id="securityContextHolderAwareRequestFilter" <br />           class="org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter"><br />   </beans:bean><br />   <beans:bean id="anonymousAuthenticationFilter" <br />           class="org.springframework.security.web.authentication.AnonymousAuthenticationFilter"><br />           <beans:property name="userAttribute" ref="anonymousUserAttribute"></beans:property><br />           <beans:property name="key"      value="anonymousUser"/><br />   </beans:bean><br />   <beans:bean id="sessionManagementFilter" <br />           class="org.springframework.security.web.session.SessionManagementFilter"><br />           <beans:constructor-arg  type="org.springframework.security.web.context.SecurityContextRepository" ref="sessionSecurityContextRepository"/><br />   </beans:bean><br />   <beans:bean id="exceptionTranslationFilter" <br />           class="org.springframework.security.web.access.ExceptionTranslationFilter"><br />           <beans:property name="authenticationEntryPoint" ref="authenticationProcessingFilterEntryPoint"/><br />   </beans:bean><br />   <beans:bean id="filterSecurityInterceptor" <br />           class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor"><br />           <beans:property name="authenticationManager"  ref="authenticationManager" /> <br />           <beans:property name="accessDecisionManager"  ref="accessDecisionManager" /> <br />           <beans:property name="securityMetadataSource" ref="securityMetadataSource" /><br />   </beans:bean><br />   <br />   <!-- The following beans are configured for the filters upstairs --><br />   <!-- ///////////////////////////////////////// --><br />   <!-- ////for LogoutFilter///////////////////// --><br />   <!-- ///////////////////////////////////////// --><br />   <beans:bean id="securityContextLogoutHandler" <br />           class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler"><br />   </beans:bean><br />   <!-- ///////////////////////////////////////// --><br />   <!-- ////for AnonymousAuthenticationFilter//// --><br />   <!-- ///////////////////////////////////////// --><br />   <beans:bean id="anonymousUserAttribute" <br />           class="org.springframework.security.core.userdetails.memory.UserAttribute"><br />           <beans:property name="authorities"><br />             <beans:list><br />                <beans:ref  bean="anonymousUserGrantedAuthority" /><br />             </beans:list><br />           </beans:property><br />           <beans:property name="password" value="anonymousUser"/><br />   </beans:bean><br />   <beans:bean id="anonymousUserGrantedAuthority" <br />           class="org.springframework.security.core.authority.GrantedAuthorityImpl"><br />           <beans:constructor-arg type="java.lang.String" value="ROLE_ANONYMOUS"/><br />   </beans:bean><br />   <!-- ///////////////////////////////////////// --><br />   <!-- ////for SessionManagementFilter////////// --><br />   <!-- ///////////////////////////////////////// --><br />   <beans:bean id="sessionSecurityContextRepository" <br />           class="org.springframework.security.web.context.HttpSessionSecurityContextRepository"><br />   </beans:bean><br />   <!-- ///////////////////////////////////////// --><br />   <!-- ////for FilterSecurityInterceptor//////// --><br />   <!-- ///////////////////////////////////////// --><br />   <beans:bean id="accessDecisionManager" <br />           class="org.springframework.security.access.vote.AffirmativeBased"><br />           <beans:property name="decisionVoters"><br />             <beans:list><br />                <beans:ref bean="webExpressionVoter"/><br />             </beans:list><br />           </beans:property><br />   </beans:bean><br />   <beans:bean id="webExpressionVoter" <br />           class="com.saveworld.authentication.web.access.expression.MyWebExpressionVoter"><br />   </beans:bean><br />   <beans:bean id="securityMetadataSource" <br />           class="com.saveworld.authentication.web.access.intercept.MyFilterInvocationSecurityMetadataSource"><br />           <beans:constructor-arg type="org.springframework.security.web.util.UrlMatcher" ref="urlMatcher" /><br />           <beans:constructor-arg type="javax.sql.DataSource" ref="proxoolDataSource" /><br />           <beans:constructor-arg type="org.springframework.security.web.access.expression.WebSecurityExpressionHandler" <br />                                      ref="expressionHandler" /><br />   </beans:bean><br />   <beans:bean id="urlMatcher"<br />           class="org.springframework.security.web.util.AntUrlPathMatcher" ><br />           <beans:constructor-arg type="boolean" value="true" /><br />   </beans:bean><br />   <beans:bean id="expressionHandler" <br />           class="org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler"><br />   </beans:bean><br /> q里做几点说明:(x)<br />    (1) 数据库中的权限相关的表:(x)<br />             ROLES<br />             AUTHORITIES<br />             USER_AUTHS<br />             ROLE_AUTHS<br />             USERS<br />        q里的表l构q(sh)是最l的Q所以就不发上来误导兄弟姐妹们了(jin)?br />        关键是看我们如何加蝲q些持久化的东西?br />        q个p看看filterSecurityInterceptor?jin),它里面用?jin)一个securityMetadataSourceQ本地的securityMetadataSource实现代码Q?br />       public class MyFilterInvocationSecurityMetadataSource extends DefaultFilterInvocationSecurityMetadataSource{<br />     private final static Log logger = LogFactory.getLog(ExpressionBasedFilterInvocationSecurityMetadataSource.class);<br />     private DataSource datasource;<br />     <br />     public MyFilterInvocationSecurityMetadataSource(UrlMatcher urlMatcher,<br />                                                     DataSource datasource,<br />                                                     WebSecurityExpressionHandler expressionHandler) {<br />         super(urlMatcher, processMap(initializeFromDb(datasource,null),expressionHandler.getExpressionParser()));<br />     }<br /> <br />     //This method is usefulless for now!<br />     //Because this method is used for parsing the expression kind<br />     private static LinkedHashMap<RequestKey, Collection<ConfigAttribute>> processMap(<br />             LinkedHashMap<RequestKey,Collection<ConfigAttribute>> requestMap, ExpressionParser parser) {<br />         Assert.notNull(parser, "SecurityExpressionHandler returned a null parser object");<br /> <br />         LinkedHashMap<RequestKey, Collection<ConfigAttribute>> requestToExpressionAttributesMap =<br />             new LinkedHashMap<RequestKey, Collection<ConfigAttribute>>(requestMap);<br /> <br />         for (Map.Entry<RequestKey, Collection<ConfigAttribute>> entry : requestMap.entrySet()) {<br />             RequestKey request = entry.getKey();<br />             Assert.isTrue(entry.getValue().size() == 1, "Expected a single expression attribute for " + request);<br />             ArrayList<ConfigAttribute> attributes = new ArrayList<ConfigAttribute>(1);<br />             String expression = entry.getValue().toArray(new ConfigAttribute[1])[0].getAttribute();<br />             logger.debug("Adding web access control expression '" + expression + "', for " + request);<br />             try {<br />                 //Replacing WebExpressionConfigAttribute with MyWebExpressionConfigAttribute <br />                 //which is defined locally!<br />                 attributes.add(new MyWebExpressionConfigAttribute(parser.parseExpression(expression)));<br />             } catch (ParseException e) {<br />                 throw new IllegalArgumentException("Failed to parse expression '" + expression + "'");<br />             }<br /> <br />             requestToExpressionAttributesMap.put(request, attributes);<br />         }<br /> <br />         return requestToExpressionAttributesMap;<br />     }<br /> <br />     private static LinkedHashMap<RequestKey,Collection<ConfigAttribute>> initializeFromDb(DataSource datasource,LinkedHashMap<RequestKey, Collection<ConfigAttribute>> configMap){<br />         LinkedHashMap<RequestKey,Collection<ConfigAttribute>> result = <br />             new LinkedHashMap<RequestKey, Collection<ConfigAttribute>>();<br />         Connection conn = null;<br />         Statement  stmt = null;<br />         ResultSet  rs   = null;<br />         try {<br />             conn = datasource.getConnection();<br />             stmt = conn.createStatement();<br />             StringBuilder sql = new StringBuilder("SELECT b.AUTHORITYPATTERN ,'hasRole('||chr(39)||a.ROLENAME||chr(39)||')' rolename ")<br />                                              .append(" FROM ROLES a,AUTHORITIES b,ROLE_AUTHS c ")<br />                                              .append(" WHERE a.rolename = c.rolename AND b.authorityname = c.authorityname");<br />             <br />             rs = stmt.executeQuery(sql.toString());<br />             String roles = "";<br />             RequestKey key = null;<br />             List<ConfigAttribute> value = null;<br />             while(rs != null && rs.next()){<br />                 key = new RequestKey(rs.getString(1));<br />                 roles = rs.getString(2);<br />                 String[] roleArray = roles.split(",|\\s+|;");<br />                 value = new ArrayList<ConfigAttribute>();<br />                 for(String role : roleArray){<br />                     ConfigAttribute config = new SecurityConfig(role);<br />                     value.add(config);<br />                 }<br />                 result.put(key, value);<br />             }<br />             //just for test<br />         } catch (SQLException e) {<br />             e.printStackTrace();<br />         } finally{<br />             try{<br />                 rs.close();<br />                 stmt.close();<br />                 conn.close();<br />             }catch(SQLException e){<br />                 e.printStackTrace();<br />             }<br />         }<br />         return result;<br />     }<br />     <br />     <br />     <br />     public boolean supports(Class<?> clazz) {<br />         return FilterInvocation.class.isAssignableFrom(clazz);<br />     }<br /> <br />     public DataSource getDatasource() {<br />         return datasource;<br />     }<br /> <br />     public void setDatasource(DataSource datasource) {<br />         this.datasource = datasource;<br />     }<br /> }<br />  (2) expressionHandler:<br />      q个东西要单独说_(d)我这里用的是表达式来(g)用戯色的Q所以,我用org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler来处理了(jin)Q还有其他的方式Q就是直接用角色q行判断Q那样会(x)更好Q这里就不描qC(jin)Q?br /> <br /> <br /> <img src ="http://www.aygfsteel.com/taochen1984/aggbug/310744.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/taochen1984/" target="_blank">taochen</a> 2010-01-25 16:29 <a href="http://www.aygfsteel.com/taochen1984/articles/310744.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>SpringSecurity使用记录Q六Q?- 本地配置一http://www.aygfsteel.com/taochen1984/articles/310221.htmltaochentaochenMon, 25 Jan 2010 07:56:00 GMThttp://www.aygfsteel.com/taochen1984/articles/310221.htmlhttp://www.aygfsteel.com/taochen1984/comments/310221.htmlhttp://www.aygfsteel.com/taochen1984/articles/310221.html#Feedback0http://www.aygfsteel.com/taochen1984/comments/commentRss/310221.htmlhttp://www.aygfsteel.com/taochen1984/services/trackbacks/310221.html 但是Q我们这里的需求有点蹊P是通过spring contextq行权限配置太不方便Q你x(chng)能让人家客户通过spring xml来配|权限吗Q不能,坚决不能Q所以,我就单步跟踪获取里面的东西(q种Ҏ(gu)比直接看代码快点Q而且可以知道里面的逻辑l构Q)(j)
那就开始吧Q?br /> 1.配置FilterChainProxyQ?br />   SpringSecurity的验证过E是通过一pd的filter来实现的?br />   q种chain的设计模式比较经典,可以说相当经典!
  看看代码实现Q?br />   上篇中说q,默认的配|要?lt;filter-name>springSecurityFilterChain</filter-name>Q那q个springSecurityFilterChain是怎么来用的呢Q?br />   public class DelegatingFilterProxy extends GenericFilterBean {
  ... ... ...
  protected void initFilterBean() throws ServletException {
        // If no target bean name specified, use filter name.
        if (this.targetBeanName == null) {
            this.targetBeanName = getFilterName();
        }

        // Fetch Spring root application context and initialize the delegate early,
        // if possible. If the root application context will be started after this
        // filter proxy, we'll have to resort to lazy initialization.
        synchronized (this.delegateMonitor) {
            WebApplicationContext wac = findWebApplicationContext();
            if (wac != null) {
                this.delegate = initDelegate(wac);
            }
        }
    }
  .....
  }
  不用_(d)你会(x)猜到我们没有配置qtargetBeanNameq个属性,所以,有?jin)this.targetBeanName = getFilterName();q样的话׃(x)配置FilterChainProxy?jin),因?f)FilterChainProxy在springContext中id是springSecurityFilterChainQ所以我们要通过自己的数据库方式配置的话Q就要琢这个FilterChainProxy?jin)?br />   所以,首先做点q样的配|吧Q?br />   <beans:bean id="myFilterChain" class="org.springframework.security.web.FilterChainProxy" >
      <filter-chain-map path-type="ant">
          <filter-chain pattern="/login.jsp*" filters="none"/>
          <filter-chain pattern="/**" filters="securityContextPersistenceFilter,
                                               logoutFilter,
                                               myUsernamePasswordAuthenticationFilter,
                                               basicAuthenticationFilter,
                                               requestCacheAwareFilter,
                                               securityContextHolderAwareRequestFilter,
                                               anonymousAuthenticationFilter,
                                               sessionManagementFilter,
                                               exceptionTranslationFilter,
                                               filterSecurityInterceptor"/>
      </filter-chain-map>
  </beans:bean>
q个里面配置的id为myFilterChainQ所以要在web.xml里面做相应配|:(x)
   <filter>
      <filter-name>myFilterChain</filter-name>
      <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
  </filter>
  <filter-mapping>
      <filter-name>myFilterChain</filter-name>
      <url-pattern>/*</url-pattern>
  </filter-mapping>
而且Q尤为重要的是要配置上这些过滤器Q?br /> filter-chain pattern="/**" filters="securityContextPersistenceFilter,logoutFilter,
                                               myUsernamePasswordAuthenticationFilter,
                                               basicAuthenticationFilter,
                                               requestCacheAwareFilter,
                                               securityContextHolderAwareRequestFilter,
                                               anonymousAuthenticationFilter,
                                               sessionManagementFilter,
                                               exceptionTranslationFilter,
                                               filterSecurityInterceptor"
针对q些qo(h)器的用途,在spring security的文档中有详l描qͼq里不多说了(jin)Q在文档中的具体位置?.2 FilterChainProxyQ看看这一章就?x)有感觉了(jin),不过l知此事要躬行啊Q?br /> 完成q些配置之后Q我们就是把入口给搭徏好了(jin)Q?br /> 鉴于文档幅Q换C接着说?br />


taochen 2010-01-25 15:56 发表评论
]]>
SpringSecurity使用记录Q五Q?- 配置http://www.aygfsteel.com/taochen1984/articles/310072.htmltaochentaochenTue, 19 Jan 2010 06:19:00 GMThttp://www.aygfsteel.com/taochen1984/articles/310072.htmlhttp://www.aygfsteel.com/taochen1984/comments/310072.htmlhttp://www.aygfsteel.com/taochen1984/articles/310072.html#Feedback0http://www.aygfsteel.com/taochen1984/comments/commentRss/310072.htmlhttp://www.aygfsteel.com/taochen1984/services/trackbacks/310072.html l于Q在无数ơ的沮下,E微看到?jin)点光亮Q前面的文章太过皮毛Q接下来的一些,希望能更加实际的Q更加深入的分析每一个过E!

一直通过默认配置q行讄Q?br /> namespace(是security 3.0,|上也看C些兄弟描q的?.0Q但是L不符合我q里的namespace配置):
<beans:beans xmlns="http://www.springframework.org/schema/security"
           xmlns:beans="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           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">
按照默认配置的httpQ这是用来根据namespace讄的基本的securityqo(h)器chainQ:(x)
auto-config=trueӞq当于
  <http>
    <form-login />
    <http-basic />
    <logout />
  </http>
也就是用了(jin)默认的过滤器?br /> 我最开始的x(chng)是能够把本地的login信息Q不是调用spring security的loginҎ(gu)Q,传入到spring security的验证过滤器里面?br /> q里有一个比较关键的问题Q就是封装他们的qo(h)器(或者仅仅是知道他们到底是哪些过滤器在v作用Q:(x)
?
AliasFilter ClassNamespace Element or Attribute
CHANNEL_FILTER ChannelProcessingFilter http/intercept-url@requires-channel
CONCURRENT_SESSION_FILTER ConcurrentSessionFilter session-management/concurrency-control
SECURITY_CONTEXT_FILTER SecurityContextPersistenceFilter http
LOGOUT_FILTER LogoutFilter http/logout
X509_FILTER X509AuthenticationFilter http/x509
PRE_AUTH_FILTER AstractPreAuthenticatedProcessingFilter Subclasses N/A
CAS_FILTER CasAuthenticationFilter N/A
FORM_LOGIN_FILTER UsernamePasswordAuthenticationFilter http/form-login
BASIC_AUTH_FILTER BasicAuthenticationFilter http/http-basic
SERVLET_API_SUPPORT_FILTER SecurityContextHolderAwareFilter http/@servlet-api-provision
REMEMBER_ME_FILTER RememberMeAuthenticationFilter http/remember-me
ANONYMOUS_FILTER AnonymousAuthenticationFilter http/anonymous
SESSION_MANAGEMENT_FILTER SessionManagementFilter session-management
EXCEPTION_TRANSLATION_FILTER ExceptionTranslationFilter http
FILTER_SECURITY_INTERCEPTOR FilterSecurityInterceptor http
SWITCH_USER_FILTER SwitchUserFilter N/A


Q最开始看的时候,把这个表格忽略了(jin)Q现在看来这些就是我们想要的Q)(j)
我们的验证过E,是按照q样的顺序进行的。自上而下q行?br />
如果我们要自己定制相应的验证处理Ҏ(gu)Q在qo(h)器里面)(j)Q我们就可以对照上面的过滤器Q覆盖相应的接口Ҏ(gu)?br /> Ҏ(gu)我的处理q程Q主要是用户名密码的验证q程Q我大体描述一下自q配置和处理过E:(x)
1.配置namespace的标{?
  <http  use-expressions="true" ><!-- This is not the default value -->
       <custom-filter position="FORM_LOGIN_FILTER" ref="myFilter"/> <!--This is my own filter which just extends AbstractAuthenticationProcessingFilter as what UsernamePasswordAuthenticationFilter does.-->
       <intercept-url pattern="/test/**"  access="hasRole('ROLE_MY')"/><!-- I tested that what is role,and how I can use it.So ROLE_MY is just a role name I defined.-->
       <intercept-url pattern="/login.jsp*" access="permitAll" />
       <logout />
       <anonymous />
       <http-basic />
  </http>
q里的问题是Q要定制自己的过滤器Q就要通过<custom-filter/>Q然后对?? 中指定的position,覆盖默认的filter?br /> 2.我的form-login  filter配置Q这些配|都是在application-security.xml文g中)(j)为:(x)
<beans:bean id="myFilter"
      class="com.saveworld.authentication.filters.MyUsernamePasswordAuthenticationFilter">
    <beans:property name="defaultTargetUrl"  value="/default.jsp" />
    <beans:property name="defaultFailureUrl"  value="/error.jsp" />
    <beans:property name="authenticationManager" ref="authenticationManager" />
    <beans:property name="filterProcessesUrl" value="/j_spring_security_check" />
    <beans:property name="continueChainBeforeSuccessfulAuthentication" value="false" />
  </beans:bean>

NOTEQ?br /> 在这里有个问题就是:(x) filter position conflicts!
如果使用q样的配|?br /> <http auto-config='true'>
   <custom-filter position="FORM_LOGIN_FILTER" ref="myFilter"/>
</http>
自定义的filter对应的position是FORM_LOGIN_FILTER
但是因ؓ(f)使用?jin)auto-config='true'Q所以默认有<form-login />Qwhich is on the position FORM_LOGIN_FILTER!
q时׃(x)出现position conflicts问题?sh)(jin)。当?dng)如果你没有设|a(chn)uto-config='true'Q但是却自己讄?lt;form-login />Q呵呵,q个情况是自己大意?jin),q是有了(jin)position conflicts的异常,所以,好好看看上面的表格是相当必要的,看清楚每个position默认都对应那些namespaceQ都是对应的哪些filterQ?br />
接着Q?br /> 我的cMyUsernamePasswordAuthenticationFilter实现Q我的说明方式就按照哪里需要,哪里加入的方式了(jin)Q:(x)
package com.saveworld.authentication.filters;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.authentication.event.InteractiveAuthenticationSuccessEvent;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.NullRememberMeServices;
import org.springframework.security.web.authentication.RememberMeServices;
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
import org.springframework.security.web.util.TextEscapeUtils;
import org.springframework.util.Assert;

import com.saveworld.authentication.handlers.MySavedRequestAwareAuthenticationSuccessHandler;
import com.saveworld.authentication.handlers.MySimpleUrlAuthenticationFailureHandler;

public class MyUsernamePasswordAuthenticationFilter extends AbstractAuthenticationProcessingFilter{
    //~ Static fields/initializers =====================================================================================

    public static final String SPRING_SECURITY_FORM_USERNAME_KEY = "username";
    public static final String SPRING_SECURITY_FORM_PASSWORD_KEY = "password";
    public static final String SPRING_SECURITY_LAST_USERNAME_KEY = "SPRING_SECURITY_LAST_USERNAME";

    private String usernameParameter = SPRING_SECURITY_FORM_USERNAME_KEY;
    private String passwordParameter = SPRING_SECURITY_FORM_PASSWORD_KEY;
    private boolean postOnly = true;
   
    private boolean allowSessionCreation = true;
   
    private String defaultTargetUrl = "/";
    private String defaultFailureUrl = "/login.jsp";
   
    private AuthenticationSuccessHandler successHandler = null;
    private AuthenticationFailureHandler failureHandler = null;
   
   
    private RememberMeServices rememberMeServices = null;
   
    //~ Constructors ===================================================================================================

    public MyUsernamePasswordAuthenticationFilter() {
        //初始?br />         super("/j_spring_security_check");
        this.rememberMeServices = (super.getRememberMeServices() == null)
                                     ? new NullRememberMeServices():super.getRememberMeServices();
       
    }

    //~ Methods ========================================================================================================

    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
        if (postOnly && !request.getMethod().equals("POST")) {
            throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
        }

        String username = obtainUsername(request);
        String password = obtainPassword(request);

        if (username == null) {
            username = "";
        }

        if (password == null) {
            password = "";
        }

        username = username.trim();

        UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);

        // Place the last username attempted into HttpSession for views
        HttpSession session = request.getSession(false);

        if (session != null || getAllowSessionCreation()) {
            request.getSession().setAttribute(SPRING_SECURITY_LAST_USERNAME_KEY, TextEscapeUtils.escapeEntities(username));
        }

        // Allow subclasses to set the "details" property
        setDetails(request, authRequest);

        return this.getAuthenticationManager().authenticate(authRequest);
    }

   
   
    public void successfulAuthentication(HttpServletRequest request, HttpServletResponse response,
            Authentication authResult) throws IOException, ServletException {

        if (logger.isDebugEnabled()) {
            logger.debug("Authentication success. Updating SecurityContextHolder to contain: " + authResult);
        }
       
        SecurityContextHolder.getContext().setAuthentication(authResult);

        rememberMeServices.loginSuccess(request, response, authResult);

        // Fire event
        if (this.eventPublisher != null) {
            eventPublisher.publishEvent(new InteractiveAuthenticationSuccessEvent(authResult, this.getClass()));
        }
        if(successHandler == null){
            successHandler = new MySavedRequestAwareAuthenticationSuccessHandler(getDefaultTargetUrl());
        }
        successHandler.onAuthenticationSuccess(request, response, authResult);
    }
   
    public void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response,
            AuthenticationException failed) throws IOException, ServletException {
        SecurityContextHolder.clearContext();
       
        if(failureHandler == null){
            failureHandler = new MySimpleUrlAuthenticationFailureHandler(getDefaultFailureUrl());
        }
       
        if (logger.isDebugEnabled()) {
            logger.debug("Authentication request failed: " + failed.toString());
            logger.debug("Updated SecurityContextHolder to contain null Authentication");
            logger.debug("Delegating to authentication failure handler" + failureHandler);
        }

        HttpSession session = request.getSession(false);

        if (session != null || allowSessionCreation) {
            request.getSession().setAttribute(SPRING_SECURITY_LAST_EXCEPTION_KEY, failed);
        }

        rememberMeServices.loginFail(request, response);

        failureHandler.onAuthenticationFailure(request, response, failed);
    }
   
   
    /**
     * Enables subclasses to override the composition of the password, such as by including additional values
     * and a separator.<p>This might be used for example if a postcode/zipcode was required in addition to the
     * password. A delimiter such as a pipe (|) should be used to separate the password and extended value(s). The
     * <code>AuthenticationDao</code> will need to generate the expected password in a corresponding manner.</p>
     *
     * @param request so that request attributes can be retrieved
     *
     * @return the password that will be presented in the <code>Authentication</code> request token to the
     *         <code>AuthenticationManager</code>
     */
    protected String obtainPassword(HttpServletRequest request) {
        return request.getParameter(passwordParameter);
    }

    /**
     * Enables subclasses to override the composition of the username, such as by including additional values
     * and a separator.
     *
     * @param request so that request attributes can be retrieved
     *
     * @return the username that will be presented in the <code>Authentication</code> request token to the
     *         <code>AuthenticationManager</code>
     */
    protected String obtainUsername(HttpServletRequest request) {
        return request.getParameter(usernameParameter);
    }

    /**
     * Provided so that subclasses may configure what is put into the authentication request's details
     * property.
     *
     * @param request that an authentication request is being created for
     * @param authRequest the authentication request object that should have its details set
     */
    protected void setDetails(HttpServletRequest request, UsernamePasswordAuthenticationToken authRequest) {
        authRequest.setDetails(authenticationDetailsSource.buildDetails(request));
    }

    /**
     * Sets the parameter name which will be used to obtain the username from the login request.
     *
     * @param usernameParameter the parameter name. Defaults to "j_username".
     */
    public void setUsernameParameter(String usernameParameter) {
        Assert.hasText(usernameParameter, "Username parameter must not be empty or null");
        this.usernameParameter = usernameParameter;
    }

    /**
     * Sets the parameter name which will be used to obtain the password from the login request..
     *
     * @param passwordParameter the parameter name. Defaults to "j_password".
     */
    public void setPasswordParameter(String passwordParameter) {
        Assert.hasText(passwordParameter, "Password parameter must not be empty or null");
        this.passwordParameter = passwordParameter;
    }

    /**
     * Defines whether only HTTP POST requests will be allowed by this filter.
     * If set to true, and an authentication request is received which is not a POST request, an exception will
     * be raised immediately and authentication will not be attempted. The <tt>unsuccessfulAuthentication()</tt> method
     * will be called as if handling a failed authentication.
     * <p>
     * Defaults to <tt>true</tt> but may be overridden by subclasses.
     */
    public void setPostOnly(boolean postOnly) {
        this.postOnly = postOnly;
    }

    public final String getUsernameParameter() {
        return usernameParameter;
    }

    public final String getPasswordParameter() {
        return passwordParameter;
    }

    public String getDefaultTargetUrl() {
        return defaultTargetUrl;
    }

    public void setDefaultTargetUrl(String defaultTargetUrl) {
        this.defaultTargetUrl = defaultTargetUrl;
    }

    public String getDefaultFailureUrl() {
        return defaultFailureUrl;
    }

    public void setDefaultFailureUrl(String defaultFailureUrl) {
        this.defaultFailureUrl = defaultFailureUrl;
    }
   
   
}

q里要关注的是几个字段Q?br />     <beans:property name="defaultTargetUrl"  value="/default.jsp" />
    <beans:property name="defaultFailureUrl"  value="/error.jsp" />
q两个字D|指定验证成功或失败后转向的页面,q里要注意是?#8220;/”开_(d)否则在AbstractAuthenticationTargetUrlRequestHandler中调用setDefaultTargetUrlҎ(gu)时会(x)抛出"defaultTarget must start with '/' or with 'http(s)'"的异常!
默认情况下,FORM_LOGIN_FILTER对应的target url和failure url都是通过 <form-login />中的default-target-url,authentication-failure-url指定Q也可以通过指定authentication-success-handler-ref?/strong>authentication-failure-handler-ref来实现认证成功和p|之后的处理方?在我的filter中,是自定义?jin)两个handler分别对应成功的和p|的验证?br />
3.用户信息获取和验证:(x)
  <authentication-manager alias="authenticationManager">
    <authentication-provider user-service-ref='myUserDetailsService'/>
  </authentication-manager>
  <beans:bean id="myUserDetailsService" class="com.saveworld.userdetails.MyUserDetailsService"></beans:bean>
q个指定的authentication-manager是用默认的ProviderManagerQ这个manager是在哪里使用的呢Q?br /> 看看MyUsernamePasswordAuthenticationFilter中的attemptAuthenticationҎ(gu)的最后一行,q里是获取指定的authentication-manager。getAuthenticationManager是从父类AbstractAuthenticationProcessingFilterl承q来的。所以,我们?lt;authentication-manager alias="authenticationManager">中就指定?jin)一个别名authenticationManagerQ在myfilter中设|属性的引用<beans:property name="authenticationManager" ref="authenticationManager" />Q然后我们就可以通过Provider引用我们自己的用户信息验证service?jin)(eg:用户信息获取和验证)(j)Q这里实际是使用?jin)Method Template模式QAbstractAuthenticationManager中设定模板函数doAuthenticationQProviderManager中做?jin)实玎ͼ?j)?br /> q里隑օ要说明一下,我们的Service是如何被调用的,我们做了(jin)配置<authentication-provider user-service-ref='myUserDetailsService'/>
指定?jin)我们的UserDetailsServiceQ类实现(Z(jin)试和理解,The easier the better!)Q?br /> package com.saveworld.userdetails;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.springframework.dao.DataAccessException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.GrantedAuthorityImpl;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

public class MyUserDetailsService implements UserDetailsService{
   
    private HashMap<String, User> userDetails = new HashMap<String, User>();
    private HashMap<String, List<GrantedAuthority>> userAuthorities = new HashMap<String, List<GrantedAuthority>>();
   
    public MyUserDetailsService(){
        //Make up a user named 'rod' with 'rod' as his password!
        //
        String username = "rod";
        String password = "1";
        boolean enabled = true;
        //purview for rod
        GrantedAuthority specAuth = new GrantedAuthorityImpl("ROLE_MY");
        List<GrantedAuthority> rodsAuthsList = new ArrayList<GrantedAuthority>();
        rodsAuthsList.add(specAuth);
//        userAuthorities.put("rod", rodsAuthsList);
        userDetails.put("rod", new User(username, password, enabled, true, true, true, rodsAuthsList));
    }
   
   
    public UserDetails loadUserByUsername(String username)
            throws UsernameNotFoundException, DataAccessException {
        System.out.println("验证从此地过?jin)一?);
        return userDetails.get(username);
    }

}
通过DaoAuthenticationProvider中的userDetailsService兌我们的UserDetailsServiceQ不得不提的是,AbstractUserDetailsAuthenticationProvider中有讑֮?jin)模板函数retrieveUserQDaoAuthenticationProviderq行?jin)实玎ͼ通过retrieveUserҎ(gu)调用UserDetailsService.loadUserByUsernameQ然后在AbstractUserDetailsAuthenticationProvider.authenticateҎ(gu)q行验证Q?br /> 接下来就是看验证的结果了(jin)Q是否成功,q入filter chain中?br /> q一切就q么有条不紊的进行了(jin)Q呵呵,ȝ是有Ҏ(gu)果了(jin)Q有?jin)一点点感性的认识?jin)!上面的描qC隑օ?x)有些؜乱,但是量是哪里需要,哪里做说明Q?br />
下篇中说明entrypoint的用处吧Q?br />

taochen 2010-01-19 14:19 发表评论
]]>
SpringSecurity使用记录Q二Q?-核心(j)分析?/title><link>http://www.aygfsteel.com/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.aygfsteel.com/taochen1984/articles/307275.html</guid><wfw:comment>http://www.aygfsteel.com/taochen1984/comments/307275.html</wfw:comment><comments>http://www.aygfsteel.com/taochen1984/articles/307275.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/taochen1984/comments/commentRss/307275.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/taochen1984/services/trackbacks/307275.html</trackback:ping><description><![CDATA[不得不再感叹一下,{略模式在SpringSecurity中用的地方太多了(jin)Q?br /> <br /> ? SecurityContextHolder, to provide access to the SecurityContext.<br /> ? SecurityContext,  to  hold  the  Authentication  and  possibly  request-specific  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 /> Q以上是从文档里面抄出来的!Q?br /> q就是权限的核心(j)?jin)!Q(持箋(hu)修改中。。。。。。)(j)<br /> <img src ="http://www.aygfsteel.com/taochen1984/aggbug/307275.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/taochen1984/" target="_blank">taochen</a> 2009-12-25 15:53 <a href="http://www.aygfsteel.com/taochen1984/articles/307275.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>SpringSecurity使用记录Q一Q?/title><link>http://www.aygfsteel.com/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.aygfsteel.com/taochen1984/articles/307203.html</guid><wfw:comment>http://www.aygfsteel.com/taochen1984/comments/307203.html</wfw:comment><comments>http://www.aygfsteel.com/taochen1984/articles/307203.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/taochen1984/comments/commentRss/307203.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/taochen1984/services/trackbacks/307203.html</trackback:ping><description><![CDATA[W一ơ配|和使用SpringSecurityQL要碰很多ơ墙Q?br /> 先说说个人理解的它里面比较有意义的架构?br /> 里面有好多设计模式的影子Q策略模式,代理模式Q工厂模式,链条模式=====Q看到这些模式(除了(jin)工厂或单例)(j)?j)里L?x)有些兴奋,ȝ是看C(jin)模式的真正练兵场Q跟兄弟们好好分享一?(才看?jin)一天!有不对之处,q望各位斧正Q?<br /> {略模式QStrategy PatternQ?<br /> 主要说一下session相关的这个策略模式,以SessionAuthenticationStrategy接口的策略划分,Ҏ(gu)我们的session安全{略Q指定不同的{略Q现在看是这U布局Q?br /> <table border="0" cellpadding="2" cellspacing="2" width="853" height="280"> <tbody> <tr> <td> 层接口</td> <td> SessionAuthenticationStrategy</td> <td> </td> <td> </td> </tr> <tr> <td> 具体实现</td> <td> SessionFixationProtectionStrategy<br /> Q直接默认实玎ͼ(j)</td> <td> NullAuthenticatedSessionStrategy<br /> Q空实现Q?br /> </td> <td> </td> </tr> <tr> <td> 二实现</td> <td> ConcurrentSessionControlStrategy</td> <td> </td> <td> </td> </tr> </tbody> </table> <br /> d比较ȝ(ch)Q各位还是凑合着看吧Q说明一下:(x)层接口被下?#8220;具体实现”两个cd玎ͼ?#8220;二实现”实现SessionFixationProtectionStrategy。具体采用哪U策略要看我们的配置?jin)?br /> 代理模式QProxyQ:(x)<br /> 很明昄代理c,DelegatingFilterProxy和FilterChainProxyQ这两个cȝ着?j)里都痒痒的Q呵呵,q_L看代理模式呀什么的Q即时看着例子也不t实Q现在看到这两个东西Q心(j)里突然有U^?rn)的Ȁ动!<br /> q两个代理类以FilterChainProxyZ说明一下吧QFilterChainProxy代理?jin)权限验证Filters的工作,通过它来讉K整个qo(h)器串里面的过滤器?br /> Chain模式Q这个也应该以FilterChainProxyq个cd口来分析Q呵呵,有兴的各位通过q个来看看吧Q?br /> <img src ="http://www.aygfsteel.com/taochen1984/aggbug/307203.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/taochen1984/" target="_blank">taochen</a> 2009-12-24 20:05 <a href="http://www.aygfsteel.com/taochen1984/articles/307203.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss> <footer> <div class="friendship-link"> <a href="http://www.aygfsteel.com/" title="狠狠久久亚洲欧美专区_中文字幕亚洲综合久久202_国产精品亚洲第五区在线_日本免费网站视频">狠狠久久亚洲欧美专区_中文字幕亚洲综合久久202_国产精品亚洲第五区在线_日本免费网站视频</a> </div> </footer> վ֩ģ壺 <a href="http://" target="_blank">Ϫ</a>| <a href="http://" target="_blank">ɽ</a>| <a href="http://" target="_blank">ɽ</a>| <a href="http://" target="_blank">ζ</a>| <a href="http://" target="_blank">Ұ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">̶</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ƽ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ͬ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ɽ</a>| <a href="http://" target="_blank">۲</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ɳƺ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">Ů</a>| <a href="http://" target="_blank">Դ</a>| <a href="http://" target="_blank">ҵ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ʻ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ƽ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ֿ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">Ǭ</a>| <a href="http://" target="_blank">ƽ</a>| <a href="http://" target="_blank">ְ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <script> (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> </body>