zoukankan      html  css  js  c++  java
  • 使用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中实现用户名密码验证。

  • 相关阅读:
    万豪酒店数据库遭入侵 5亿顾客信息或泄露
    网络信息安全中最热门的果然是它
    有奖问卷调查丨你有意见?可以提啊!
    业务逻辑漏洞探索之绕过验证
    一个月薪两万的Web安全工程师要掌握哪些技能?
    phpcms2008远程代码执行漏洞
    BASE64编码原理分析脚本实现及逆向案例
    源码级调试的XNU内核
    使用RSA加密在Python中逆向shell
    感恩节活动中奖名单 i春秋喊你领礼物啦!
  • 原文地址:https://www.cnblogs.com/hzcxy/p/3012286.html
Copyright © 2011-2022 走看看