未调用 Spring Security j_spring_security_check

Posted

技术标签:

【中文标题】未调用 Spring Security j_spring_security_check【英文标题】:Spring Security j_spring_security_check not invoked 【发布时间】:2013-05-03 08:30:32 【问题描述】:

我有一个 Spring WebApp 使用自定义用户、角色、权限表自定义(阅读“幼稚”)身份验证。

我现在正在迁移代码以使用 Spring Security。我阅读了教程并达到了可以匿名访问我的 login.jsp 页面、css、js、png 文件的地步。我有一个动作属性为“j_spring_security_check”的表单。在提交表单时,浏览器会向该 URL 执行 HTTP Post,这会导致 404。

现在我没有使用 RequestMapping 映射 j_spring_security_check。这是必需的吗?我们什么时候应该有这个 URL 的请求映射?

在我的身份验证提供程序中,我提供了对实现 UserDetailsS​​ervice 的类的 bean 的引用。我期待 Spring 通过调用 loadUserByUserName 来执行身份验证,但这个方法永远不会被调用。为什么没有调用该方法?我是否误解了身份验证应该如何工作?我是否需要为 j_spring_security_check 提供自定义请求映射才能使其工作?

这是我的自定义用户详细信息服务:

@Service(value="myUserDetailsService")
public class LoginUserService implements UserDetailsService 

  @Autowired
  private UserRepository userRepository;

  @Override
  public UserDetails loadUserByUsername(String username)
      throws UsernameNotFoundException 

    System.out.println("here");

    User user = userRepository.findUser(username);
    if (user != null)
      return new V2VUserDetails(user);
    else
      return null;
  


这是我的安全 XML:

    <http pattern="/**/*.css" security="none" />
    <http pattern="/**/*.js" security="none" />
    <http pattern="/**/*.png" security="none" />

    <http auto-config="true">
      <intercept-url pattern="/login.html*" access="IS_AUTHENTICATED_ANONYMOUSLY" />
      <intercept-url pattern="/j_spring_security_check" access="IS_AUTHENTICATED_ANONYMOUSLY" />
      <intercept-url pattern="/**" access="ROLE_USER" />
      <form-login login-page="/login.html"
                  login-processing-url="/j_spring_security_check"
                  default-target-url="/welcomePage.html"
                  authentication-failure-url="/welcomePage.html"
                  always-use-default-target="true" />
    </http>

  <authentication-manager>
    <authentication-provider user-service-ref='myUserDetailsService'/>
  </authentication-manager>

  <beans:bean id="myUserDetailsService"
    class="security.LoginUserService">
  </beans:bean>

我在 *** 和其他网站上检查了几个答案,但无法解决问题。

编辑 尝试了here 给出的建议。现在出现 BeanFactory 未初始化错误。

编辑 上下文配置位置 /WEB-INF/security-v2v-servlet.xml

<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>
  <dispatcher>REQUEST</dispatcher>
  <dispatcher>FORWARD</dispatcher>
</filter-mapping>

更新

当前的 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"
         id="WebApp_ID" version="2.5">

    <display-name>Spring3MVC</display-name>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/security-v2v-servlet.xml</param-value>
    </context-param>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
    <error-page>
        <error-code>500</error-code>
        <location>/errorPage.jsp</location>
    </error-page>
    <error-page>
        <error-code>404</error-code>
        <location>/errorPage.jsp</location>
    </error-page>

    <servlet>
        <servlet-name>v2v</servlet-name>
        <servlet-class>
            org.springframework.web.servlet.DispatcherServlet
        </servlet-class>
        <load-on-startup>2</load-on-startup>
    </servlet>
    <servlet>
        <servlet-name>Resource Servlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.ResourceServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>v2v</servlet-name>
        <url-pattern>*.html</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>v2v</servlet-name>
        <url-pattern>*.zip</url-pattern>
    </servlet-mapping>

    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>*.css</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>*.js</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>*.jpeg</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>*.gif</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>*.png</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>/j_spring_security_check</url-pattern>
    </servlet-mapping>

    <filter>
      <filter-name>UserAddFilter</filter-name>
      <filter-class>
          filter.UserInfoAddToThreadFilter
      </filter-class>
    </filter>
    <filter-mapping>
      <filter-name>UserAddFilter</filter-name>
      <url-pattern>/*</url-pattern>
    </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>/*</url-pattern>
      <dispatcher>REQUEST</dispatcher>
      <dispatcher>FORWARD</dispatcher>
    </filter-mapping>



    <listener>
      <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
    </listener>

</web-app>

【问题讨论】:

你看到下面的答案了吗?有帮助吗? 好吧,我尝试按照您的建议删除 servlet 映射,但随后它为 j_spring_security_check 返回 404 最后还为 j_spring_security_logout 添加了 servlet 映射以使注销功能正常工作。 【参考方案1】:

您不需要为/j_spring_security_check 创建@RequestMapping,该模式会被 Spring Security Filter 拦截,并应将您引导至登录页面。

我对出了什么问题的猜测可能是您设置 Spring Security Filter 的方式。您的过滤器的 web.xml 中应该有以下条目:

<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>

并且应该通过 Root Web 应用程序上下文加载安全配置文件 - 一个通过 ContextLoaderListener 加载,而不是通过 DispatcherServlet 加载,例如:

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:/META-INF/context-security.xml</param-value>
</context-param>

如果您的配置符合这些原则,它应该可以正常工作。

【讨论】:

我的配置中有这个。它被重定向到登录页面,只是表单登录提交不起作用。 想知道这是否相关mark.koli.ch/2010/07/… 启用了 spring 安全日志,并且在 j_spring_security_check 的 POST 上查看日志中没有任何活动。这里是配置完整文件github.com/C4G/V2V/tree/… 对不起,我误解了你的问题。在没有 Spring 安全性的情况下,您能否确认您的流程可以正常工作? 是的,它可以在没有弹簧安全性的情况下工作。也适用于更新后的 web.xml,如问题所示。【参考方案2】:
    请确保您在登录表单中有操作j_spring_security_check 与您的问题无关,但我建议删除/j_spring_security_check 的匿名权限(删除以下行)。只有登录表单应该具有匿名权限。 &lt;intercept-url pattern="/j_spring_security_check" access="IS_AUTHENTICATED_ANONYMOUSLY" /&gt;

更新 请从 web.xml 中删除

<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>/j_spring_security_check</url-pattern>
</servlet-mapping>

【讨论】:

这样表单就会转到页面localhost:8080/j_spring_security_check 而不是localhost:8080/app/j_spring_security_check。我看到的是 Apache 的 404 页面,而不是我的应用程序的 HTTP 404 页面。 我的理解是 UsernamePasswordAuthenticationFilter 应该在通过网络应用程序的每个网络请求上调用。那正确吗?如果是这样,它应该检测是否正在访问 url j_spring_security_check 并相应地拦截请求并执行身份验证。它似乎没有这样做。在这个 url 上的 POST 期间在 spring security DEBUG 日志中没有看到任何内容,这仅表明 tomcat 觉得这个 URL 不是由我的 webapp 发布的,因此不会转发请求。 话虽如此,我认为我的 web.xml 中的 servlet 映射肯定存在问题。这是文件bit.ly/12fGrVh的在线副本 所以我得到了 j_spring_security_check 的请求,通过创建如下的 servlet 映射来调用我的 userDetailsS​​ervice:` default /j_spring_security_check`这是一个好方法吗?如何优化 web.xml 中的 servlet 映射?这样做的标准方法是什么?您能否详细说明这些后续问题? 我的错误-应该没有/只有j_spring_security_check

以上是关于未调用 Spring Security j_spring_security_check的主要内容,如果未能解决你的问题,请参考以下文章

Spring-security/Grails 应用程序 - 未调用自定义 WebSecurity 配置

未调用 Spring Security 自定义登录表单

Spring security - 未调用自定义 userDetailsS​​ervice 实现

未调用 Spring Security Authentication UserDetailsS​​ervice 实现类

Spring安全性j_spring_security_check调用给出404未找到错误[关闭]

Spring Security:未调用自定义 UserDetailsS​​ervice(使用 Auth0 身份验证)