使用Spring security来实现登录验证

1.我们采用数据库存储的用户信息与用户输入的表单信息进行验证比对。

在 web.xml中进行filter配置

  <filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
  </filter>

  <filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

在Spring中的配置

<?xml version="1.0" encoding="UTF-8"?>
<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.2.xsd
           http://www.springframework.org/schema/security
           http://www.springframework.org/schema/security/spring-security-3.1.xsd">
  <global-method-security pre-post-annotations="enabled" />

  <beans:bean id="authDataSource" class="org.apache.commons.dbcp.BasicDataSource">
    <beans:property name="driverClassName" value="oracle.jdbc.driver.OracleDriver">
    </beans:property>
    <beans:property name="url" value="jdbc:oracle:thin:@**:1521:dev" />
    <beans:property name="username" value="username" />
    <beans:property name="password" value="password" />
  </beans:bean>
  <beans:bean id="postSuccHandler" class="**.auth.AjaxPostSuccHandler">
    <beans:property name="defaultTargetUrl" value="/mgr/index.html" />
  </beans:bean>
  <beans:bean id="postFailHandler" class="**.auth.AjaxPostFailureHandler">
  </beans:bean>
  <beans:bean id="userDetailsService" class="org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl">
    <beans:property name="dataSource" ref="authDataSource" />
    <beans:property name="usersByUsernameQuery" value="select user_id,password,status from users where user_id = ?" />
    <beans:property name="authoritiesByUsernameQuery" value="select user_id,title from users where user_id = ?" />
  </beans:bean>

  <http use-expressions="true">
    <intercept-url pattern="/" access="isAuthenticated()" />
    <intercept-url pattern="/index.html" access="isAuthenticated()" />
    <intercept-url pattern="/index-debug.html" access="isAuthenticated()" />
    <intercept-url pattern="/**" access="permitAll" />
    <form-login login-page="/login.html" default-target-url="/index.html" authentication-failure-url="/login.html?error=1"
      authentication-success-handler-ref="postSuccHandler" authentication-failure-handler-ref="postFailHandler" />
    <logout logout-success-url="/login.html" />
    <remember-me data-source-ref="authDataSource" />
    <session-management invalid-session-url="/login.html" session-fixation-protection="newSession">
      <concurrency-control max-sessions="10" />
    </session-management>
  </http>

  <authentication-manager>
    <authentication-provider user-service-ref="userDetailsService">
      <password-encoder hash="sha-256"></password-encoder>
    </authentication-provider>
  </authentication-manager>
</beans:beans>

接下来所有的请求都由DelegatingFilterProxy接管。

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {

        // Lazily initialize the delegate if necessary.
        Filter delegateToUse = null;
        synchronized (this.delegateMonitor) {
            if (this.delegate == null) {
                WebApplicationContext wac = findWebApplicationContext();
                if (wac == null) {
                    throw new IllegalStateException("No WebApplicationContext found: no ContextLoaderListener registered?");
                }
                this.delegate = initDelegate(wac);
            }
            delegateToUse = this.delegate;
        }

        // Let the delegate perform the actual doFilter operation.
        invokeDelegate(delegateToUse, request, response, filterChain);
    }

delegate为下面这么多filter.

FilterChainProxy[Filter Chains: [[ org.springframework.security.web.util.AnyRequestMatcher@1, [org.springframework.security.web.context.SecurityContextPersistenceFilter@65ef7efe, org.springframework.security.web.session.ConcurrentSessionFilter@4e7a89fa, org.springframework.security.web.authentication.logout.LogoutFilter@4ef8a456, org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter@25ed329b, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@77957190, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@7452e245, org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter@6d855bac, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@4e45b160, org.springframework.security.web.session.SessionManagementFilter@41803dc5, org.springframework.security.web.access.ExceptionTranslationFilter@4a57721b, org.springframework.security.web.access.intercept.FilterSecurityInterceptor@330470be]]]]

FilterChainProxy中对这些filter进行处理

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        boolean clearContext = request.getAttribute(FILTER_APPLIED) == null;
        if(clearContext) {
            try {
                request.setAttribute(FILTER_APPLIED, Boolean.TRUE);
                doFilterInternal(request, response, chain);
            } finally {
                SecurityContextHolder.clearContext();
                request.removeAttribute(FILTER_APPLIED);
            }
        } else {
            doFilterInternal(request, response, chain);
        }
    }

    private void doFilterInternal(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {

        FirewalledRequest fwRequest = firewall.getFirewalledRequest((HttpServletRequest) request);
        HttpServletResponse fwResponse = firewall.getFirewalledResponse((HttpServletResponse) response);

        List<Filter> filters = getFilters(fwRequest);

        if (filters == null || filters.size() == 0) {
            if (logger.isDebugEnabled()) {
                logger.debug(UrlUtils.buildRequestUrl(fwRequest) +
                        (filters == null ? " has no matching filters" : " has an empty filter list"));
            }

            fwRequest.reset();

            chain.doFilter(fwRequest, fwResponse);

            return;
        }

        VirtualFilterChain vfc = new VirtualFilterChain(fwRequest, chain, filters);
        vfc.doFilter(fwRequest, fwResponse);
    }

在VirtualFilterChain中是通过doFilter实现

        public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException {
            if (currentPosition == size) {
                if (logger.isDebugEnabled()) {
                    logger.debug(UrlUtils.buildRequestUrl(firewalledRequest)
                            + " reached end of additional filter chain; proceeding with original chain");
                }

                // Deactivate path stripping as we exit the security filter chain
                this.firewalledRequest.reset();

                originalChain.doFilter(request, response);
            } else {
                currentPosition++;

                Filter nextFilter = additionalFilters.get(currentPosition - 1);

                if (logger.isDebugEnabled()) {
                    logger.debug(UrlUtils.buildRequestUrl(firewalledRequest) + " at position " + currentPosition + " of "
                        + size + " in additional filter chain; firing Filter: '"
                        + nextFilter.getClass().getSimpleName() + "'");
                }

                nextFilter.doFilter(request, response, this);
            }
        }

我们主要在UsernamePasswordAuthenticationFilter中实现用户名密码验证。

 

 

转载于:https://www.cnblogs.com/hzcxy/archive/2013/04/10/3012286.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值