Spring Security UserDetails服务未验证密码

Spring Security UserDetails服务未验证密码,spring,spring-security,Spring,Spring Security,我正在实现SpringSecurity3.0.5,并在基于表单的登录中扩展了SpringUserDetailsService。目前,我的登录表单只验证用户名,不验证密码。spring security在哪里验证发布到/j_spring_security_check的密码 安全配置: <?xml version="1.0" encoding="UTF-8"?> <beans:beans xmlns="http://www.springframework.org/schem

我正在实现SpringSecurity3.0.5,并在基于表单的登录中扩展了SpringUserDetailsService。目前,我的登录表单只验证用户名,不验证密码。spring security在哪里验证发布到/j_spring_security_check的密码

安全配置:

<?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:util="http://www.springframework.org/schema/util"
    xmlns:context="http://www.springframework.org/schema/context"
    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/util
    http://www.springframework.org/schema/util/spring-util-3.0.xsd
    http://www.springframework.org/schema/security
    http://www.springframework.org/schema/security/spring-security-3.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.0.xsd">
    <context:annotation-config />
    <context:component-scan base-package="dc" />
    <global-method-security />
    <http access-denied-page="/auth/denied.html">
         <intercept-url filters="none" pattern="/javax.faces.resource/**" />
         <intercept-url filters="none" pattern="/services/rest-api/1.0/**" />
         <intercept-url filters="none" pattern="/preregistered/*"/>
         <intercept-url
            pattern="/**/*.xhtml"
            access="ROLE_NONE_GETS_ACCESS" />
        <intercept-url
            pattern="/auth/**"
            access="ROLE_ANONYMOUS,ROLE_USER" />
         <intercept-url
            pattern="/auth/*"
            access="ROLE_ANONYMOUS" />
         <intercept-url
            pattern="/registered/*"
            access="ROLE_USER" />
          <intercept-url
            pattern="/*"
           access="ROLE_ANONYMOUS" />
        <form-login
            login-processing-url="/j_spring_security_check.html"
            login-page="/auth/login.html"
            default-target-url="/home.html"
            authentication-failure-url="/login.html" />
         <logout invalidate-session="true" 
              logout-url="logout.html" 
              success-handler-ref="SuccessHandler"/>
        <anonymous username="guest" granted-authority="ROLE_ANONYMOUS"/>
        <remember-me user-service-ref="userManager" key="dfdfdfdff"/>
        <custom-filter after="FORM_LOGIN_FILTER" ref="xmlAuthenticationFilter"/>
    </http>
    <!-- Configure the authentication provider -->
    <authentication-manager alias="am">
        <authentication-provider user-service-ref="userManager">
                <password-encoder ref="passwordEncoder" />
        </authentication-provider>
        <authentication-provider ref="xmlAuthenticationProvider" />
    </authentication-manager>
</beans:beans>
web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
  <context-param>
    <param-name>javax.faces.FACELETS_LIBRARIES</param-name>
    <param-value>/WEB-INF/facelet/dc.taglib.xml</param-value>
  </context-param>
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
        WEB-INF/dc-context-api.xml
        WEB-INF/dc-context-security.xml
    </param-value>
  </context-param>
  <context-param>
    <param-name>resteasy.resource.method-interceptors</param-name>
    <param-value>org.jboss.resteasy.core.ResourceMethodSecurityInterceptor</param-value>
  </context-param>
  <context-param>
    <param-name>resteasy.resources</param-name>
    <param-value>
         com.dc.web.actions.GlobalWebService</param-value>
  </context-param>
  <context-param>
    <param-name>resteasy.servlet.mapping.prefix</param-name>
    <param-value>/services/rest-api</param-value>
  </context-param>
  <context-param>
    <param-name>resteasy.media.type.mappings</param-name>
    <param-value>json : application/json, xml : application/xml</param-value>
  </context-param>
  <context-param>
    <param-name>resteasy.resources</param-name>
    <param-value>
            com.WebService
        </param-value>
  </context-param>
  <context-param>
    <param-name>primefaces.THEME</param-name>
    <param-value>none</param-value>
  </context-param>
  <context-param>
        <param-name>log4jConfigLocation</param-name>
        <param-value>/WEB-INF/log4j.properties</param-value>
    </context-param>
     <context-param>
        <param-name>log4jRefreshInterval</param-name>
        <param-value>1000</param-value>
    </context-param>
    <context-param> 
        <param-name>primefaces.PRIVATE_CAPTCHA_KEY</param-name> 
        <param-value>6LeL-MISAAAAAG6k07ch22oy-mxXBUi1MXKmrWiD</param-value>
    </context-param>
    <context-param> 
        <param-name>primefaces.PUBLIC_CAPTCHA_KEY</param-name> 
        <param-value>6LeL-MISAAAAAPTK5lYI9tK0SWWY2BqC2Hun7sH3</param-value>
    </context-param>
  <filter> 
    <filter-name>PrimeFaces FileUpload Filter</filter-name> 
        <filter-class>org.primefaces.webapp.filter.FileUploadFilter </filter-class>
        <init-param> 
            <param-name>thresholdSize</param-name> <param-value>51200</param-value>
        </init-param> 
        <init-param>
            <param-name>uploadDirectory</param-name>
            <param-value>url/upload</param-value> 
        </init-param>
    </filter>
  <filter-mapping>
    <filter-name>PrimeFaces FileUpload Filter</filter-name>
    <servlet-name>Faces Servlet</servlet-name>
  </filter-mapping>
  <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>*.html</url-pattern>
    <dispatcher>FORWARD</dispatcher>
    <dispatcher>REQUEST</dispatcher>
  </filter-mapping>
  <filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>*.xhtml</url-pattern>
    <dispatcher>FORWARD</dispatcher>
    <dispatcher>REQUEST</dispatcher>
  </filter-mapping>
  <filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/dc_security_check</url-pattern>
    <dispatcher>FORWARD</dispatcher>
    <dispatcher>REQUEST</dispatcher>
  </filter-mapping>
  <listener>
    <listener-class>org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap</listener-class>
  </listener>
  <listener>
    <listener-class>org.jboss.resteasy.plugins.spring.SpringContextLoaderListener</listener-class>
  </listener>
  <listener>
    <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
  </listener>
  <listener>
        <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
    </listener>
  <servlet>
    <servlet-name>Resteasy</servlet-name>
    <servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher</servlet-class>
  </servlet>
  <servlet>
    <servlet-name>Faces Servlet</servlet-name>
    <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>Resteasy</servlet-name>
    <url-pattern>api/*</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>*.html</url-pattern>
  </servlet-mapping>
  <session-config>
    <session-timeout>30</session-timeout>
  </session-config>
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>index.html</welcome-file>
  </welcome-file-list>
  <login-config>
    <auth-method>BASIC</auth-method>
  </login-config>
</web-app>

javax.faces.FACELETS\u库
/WEB-INF/facelet/dc.taglib.xml
上下文配置位置
WEB-INF/dc-context-api.xml
WEB-INF/dc-context-security.xml
resteasy.resource.method-interceptors
org.jboss.resteasy.core.ResourceMethodSecurityInterceptor
resteasy.resources
com.dc.web.actions.GlobalWebService
resteasy.servlet.mapping.prefix
/服务/rest api
resteasy.media.type.mappings
json:application/json,xml:application/xml
resteasy.resources
com.WebService
主题
没有一个
log4jConfigLocation
/WEB-INF/log4j.properties
log4jRefreshInterval
1000
primefaces.PRIVATE\u验证码\u密钥
6LeL-MISAAAAG6K07CH22OY-mxXBUi1MXKmrWiD
primefaces.PUBLIC\u验证码\u密钥
6LeL-MISAAAAPTK5LYI9TK0SWWY2BQC2HUN7SH3
PrimeFaces文件上载筛选器
org.primefaces.webapp.filter.FileUploadFilter
阈值大小51200
上传目录
url/上传
PrimeFaces文件上载筛选器
Facesservlet
springSecurityFilterChain
org.springframework.web.filter.DelegatingFilterProxy
springSecurityFilterChain
*.html
向前地
要求
springSecurityFilterChain
*.xhtml
向前地
要求
springSecurityFilterChain
/dc_安全检查
向前地
要求
org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap
org.jboss.resteasy.plugins.spring.SpringContextLoaderListener
org.springframework.web.context.request.RequestContextListener
org.springframework.web.util.Log4jConfigListener
放松
org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher
Facesservlet
javax.faces.webapp.FacesServlet
1.
放松
原料药/*
Facesservlet
*.html
30
index.jsp
index.html
基本的

它将您提交的密码与您的
UserDetails服务返回的
UserDetails
对象返回的密码进行比较。如果需要更多帮助,请发布您的配置和
UserDetailsService

编辑:谢谢你的信息。它完全符合你的猜测。
ProviderManager
(默认情况下使用)的JavaDoc中包含以下内容:

如果后续提供程序成功 对请求进行身份验证,越早越好 身份验证异常为 漠视与成功 将使用身份验证


因此,您的问题是后一个提供商“推翻”了第一个提供商的决定。

感谢您的帮助,我添加了我的配置和impl…我有基于表单的登录和自定义过滤器。我想知道它可能会使我的表单登录失败,并转到不需要密码的自定义表单。
import javax.inject.Inject;

import org.springframework.dao.DataAccessException;
import org.springframework.security.authentication.encoding.PasswordEncoder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.dc.api.dao.AuthorityDAO;
import com.dc.api.dao.UserDAO;
import com.dc.api.exception.ApiDataException;
import com.dc.api.exception.EmailNotFoundException;
import com.dc.api.helper.MailContentHelper;
import com.dc.api.model.Users;
import com.dc.api.model.vo.APIResponse;
import com.dc.api.service.UserManager;
import com.dc.api.service.Utilities;

@Service("userManager")
public class UserManagerImpl extends UserDetailsService {
    @Inject
    UserDAO userDAO;
    @Inject
    AuthorityDAO authorityDAO;
    @Inject
    PasswordEncoder passwordEncoder;
    @Inject
    Utilities utilities;

    private void encodePassword(Users user) {
        if (user.getPassword() == null && user.getRawPassword() != null) {
            user.setPassword(passwordEncoder.encodePassword(user.getRawPassword(), null));
            user.setRawPassword(null);
        }
    }

    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException {
        Users user = null;
        try {
            user = userDAO.findByUsername(username);
            if (user != null) {

            }
        } catch (DataAccessException ex) {
            throw new UsernameNotFoundException("Invalid login", ex);
        }
        if (user == null) {
            throw new UsernameNotFoundException("User not found.");
        }
        return user;
    }

    public Users getUser(String username) {
        try {
            return userDAO.findByUsername(username);
        } catch (DataAccessException ex) {
            // ignore
            log.warn("Duplicate username: " + username);
        }
        return null;
    }

    public boolean isUsernameTaken(String username) {
        try {
            if (userDAO.findByUsername(username) == null) {
                return false;
            } else {
                return true;
            }
        } catch (DataAccessException ex) {
            // ignore
            log.warn("Duplicate username: " + username);
        }
        return true;
    }

    public boolean isLoginValid(String username, String password) throws ApiDataException {
        Users user = null;
        try {
            user = userDAO.findByUsername(username);
        } catch (DataAccessException ex) {
            throw new ApiDataException("Data Access Exception while verifying login");
        }
        if (user == null) {
            return false;
        }
        if (passwordEncoder.isPasswordValid(user.getPassword(), password, null)) {
            return true;
        }
        return false;
    }

    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT)
    public void saveUser(Users user) {
        encodePassword(user);
        userDAO.save(user);
    }

    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT)
    public void updateUser(Users user) {
        encodePassword(user);
        userDAO.update(user);
    }

    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT)
    public void resetPassword(String username, MailContentHelper mailContentHelper) {
        String newPassword = utilities.generateSecret(8);
        this.changePassword(username, newPassword, mailContentHelper);
    }

    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT)
    public void changePassword(String username, String password, MailContentHelper mailContentHelper) {
        Users user = userDAO.findByUsername(username);
        user.setPassword(null);
        user.setRawPassword(password);
        encodePassword(user);
        userDAO.update(user);
        String firstName = user.getFirstName();
        firstName = (firstName == null) ? user.getUsername() : firstName;
        //SimpleMailMessage message = mailContentHelper.retrieveContent(new Object[]{firstName, password, user.getEmail()});
        //utilities.sendMail(message);
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
  <context-param>
    <param-name>javax.faces.FACELETS_LIBRARIES</param-name>
    <param-value>/WEB-INF/facelet/dc.taglib.xml</param-value>
  </context-param>
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
        WEB-INF/dc-context-api.xml
        WEB-INF/dc-context-security.xml
    </param-value>
  </context-param>
  <context-param>
    <param-name>resteasy.resource.method-interceptors</param-name>
    <param-value>org.jboss.resteasy.core.ResourceMethodSecurityInterceptor</param-value>
  </context-param>
  <context-param>
    <param-name>resteasy.resources</param-name>
    <param-value>
         com.dc.web.actions.GlobalWebService</param-value>
  </context-param>
  <context-param>
    <param-name>resteasy.servlet.mapping.prefix</param-name>
    <param-value>/services/rest-api</param-value>
  </context-param>
  <context-param>
    <param-name>resteasy.media.type.mappings</param-name>
    <param-value>json : application/json, xml : application/xml</param-value>
  </context-param>
  <context-param>
    <param-name>resteasy.resources</param-name>
    <param-value>
            com.WebService
        </param-value>
  </context-param>
  <context-param>
    <param-name>primefaces.THEME</param-name>
    <param-value>none</param-value>
  </context-param>
  <context-param>
        <param-name>log4jConfigLocation</param-name>
        <param-value>/WEB-INF/log4j.properties</param-value>
    </context-param>
     <context-param>
        <param-name>log4jRefreshInterval</param-name>
        <param-value>1000</param-value>
    </context-param>
    <context-param> 
        <param-name>primefaces.PRIVATE_CAPTCHA_KEY</param-name> 
        <param-value>6LeL-MISAAAAAG6k07ch22oy-mxXBUi1MXKmrWiD</param-value>
    </context-param>
    <context-param> 
        <param-name>primefaces.PUBLIC_CAPTCHA_KEY</param-name> 
        <param-value>6LeL-MISAAAAAPTK5lYI9tK0SWWY2BqC2Hun7sH3</param-value>
    </context-param>
  <filter> 
    <filter-name>PrimeFaces FileUpload Filter</filter-name> 
        <filter-class>org.primefaces.webapp.filter.FileUploadFilter </filter-class>
        <init-param> 
            <param-name>thresholdSize</param-name> <param-value>51200</param-value>
        </init-param> 
        <init-param>
            <param-name>uploadDirectory</param-name>
            <param-value>url/upload</param-value> 
        </init-param>
    </filter>
  <filter-mapping>
    <filter-name>PrimeFaces FileUpload Filter</filter-name>
    <servlet-name>Faces Servlet</servlet-name>
  </filter-mapping>
  <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>*.html</url-pattern>
    <dispatcher>FORWARD</dispatcher>
    <dispatcher>REQUEST</dispatcher>
  </filter-mapping>
  <filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>*.xhtml</url-pattern>
    <dispatcher>FORWARD</dispatcher>
    <dispatcher>REQUEST</dispatcher>
  </filter-mapping>
  <filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/dc_security_check</url-pattern>
    <dispatcher>FORWARD</dispatcher>
    <dispatcher>REQUEST</dispatcher>
  </filter-mapping>
  <listener>
    <listener-class>org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap</listener-class>
  </listener>
  <listener>
    <listener-class>org.jboss.resteasy.plugins.spring.SpringContextLoaderListener</listener-class>
  </listener>
  <listener>
    <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
  </listener>
  <listener>
        <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
    </listener>
  <servlet>
    <servlet-name>Resteasy</servlet-name>
    <servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher</servlet-class>
  </servlet>
  <servlet>
    <servlet-name>Faces Servlet</servlet-name>
    <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>Resteasy</servlet-name>
    <url-pattern>api/*</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>*.html</url-pattern>
  </servlet-mapping>
  <session-config>
    <session-timeout>30</session-timeout>
  </session-config>
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>index.html</welcome-file>
  </welcome-file-list>
  <login-config>
    <auth-method>BASIC</auth-method>
  </login-config>
</web-app>