java Spring Security 登录返回 404

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/33166139/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 21:17:04  来源:igfitidea点击:

Spring Security login returns 404

javaspringjspspring-mvcspring-security

提问by Abhisek Lamsal

I am currently working on my blog in Spring framework. I am implementing the Spring Security for login purpose. Everything works as expected until I submit the login credentials which is always returning 404 code.

我目前正在使用 Spring 框架编写我的博客。我正在为登录目的实施 Spring Security。一切都按预期进行,直到我提交始终返回 404 代码的登录凭据。

Here is my web.xml code

这是我的web.xml鳕鱼Ë

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
    http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

<display-name>avispring</display-name>          

<error-page>
    <error-code>404</error-code>
    <location>/404.html</location>
</error-page>

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/spring-database.xml</param-value>
</context-param>

<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>/admin/*</url-pattern>
</filter-mapping>

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

<servlet>
    <servlet-name>spring</servlet-name>
    <servlet-class>
        org.springframework.web.servlet.DispatcherServlet
    </servlet-class>
    <load-on-startup>1</load-on-startup>        
</servlet>
<servlet-mapping>
    <servlet-name>spring</servlet-name>
    <url-pattern>/</url-pattern>        
</servlet-mapping>

Here is my spring security code:

这是我的春季安全代码:

<bean id="dataSource"
    class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
    <property name="url" value="jdbc:mysql://localhost:3306/avispring"/>
    <property name="username" value="root"/>
    <property name="password" value=""/>
</bean>
<security:debug/>
<security:http auto-config="true">
    <security:intercept-url pattern="/admin/**" access="hasRole('ROLE_ADMIN')"/>
    <security:intercept-url pattern="/j_spring_security_check" access="permitAll"/>
    <security:form-login        
    login-page="/login.html"
    authentication-failure-url="/login?login_error=1"
    default-target-url="/admin/home.html"/>     
</security:http>

<security:authentication-manager>
    <security:authentication-provider>
        <security:jdbc-user-service 
            data-source-ref="dataSource"
            users-by-username-query="select USERNAME,PASSWORD,ENABLED from USER_AUTHENTICATION where USERNAME=?"
            authorities-by-username-query="select u1.USERNAME,u2.ROLE from USER_AUTHENTICATION u1,USER_AUTHORIZATION u2 where u1.USER_ID=u2.USER_ID and u1.USERNAME=?"/>
    </security:authentication-provider>
</security:authentication-manager>

part of my login.jsp code is

我的 login.jsp 代码的一部分是

<form action="<c:url value="/login"/>" method="post">
      <div class="form-group has-feedback">
        <input type="email" class="form-control" placeholder="Email" name="username">
        <span class="glyphicon glyphicon-envelope form-control-feedback"></span>
      </div>
      <div class="form-group has-feedback">
        <input type="password" class="form-control" placeholder="Password" name="password">
        <span class="glyphicon glyphicon-lock form-control-feedback"></span>
      </div>
      <div class="row">
        <div class="col-xs-8">
          <div class="checkbox icheck">
            <label>
              <input type="checkbox"> Remember Me
            </label>
          </div>
        </div><!-- /.col -->
        <div class="col-xs-4">
          <button type="submit" class="btn btn-primary btn-block btn-flat"     name="submit">Sign In</button>
        </div><!-- /.col -->
      </div>
    </form>

and the console output is

控制台输出是

Oct 16, 2015 1:06:03 AM org.springframework.web.servlet.DispatcherServlet noHandlerFound WARNING: No mapping found for HTTP request with URI [/avispring/login] in DispatcherServlet with name 'spring'

2015 年 10 月 16 日上午 1:06:03 org.springframework.web.servlet.DispatcherServlet noHandlerFound 警告:在名称为“spring”的 DispatcherServlet 中找不到带有 URI [/avispring/login] 的 HTTP 请求的映射

Note:

笔记:

  1. I am using spring 4.2.1 and spring security 4.0.2
  2. Most of the forums are pointing to the context path i.e [appname/login]or [appname/j_spring_security_check]and I think mine is ok regarding it
  1. 我正在使用 spring 4.2.1 和 spring security 4.0.2
  2. 大多数论坛都指向上下文路径,即[appname/login][appname/j_spring_security_check],我认为我的对此没有问题

Please help...

请帮忙...

UPDATE:

更新:

when I used log4j, the debug output at the time of form submission is as follows:

我在使用log4j的时候,提交表单时的debug输出如下:

DEBUG: org.springframework.web.servlet.DispatcherServlet - Bound request context to thread: org.apache.catalina.connector.RequestFacade@c8b445 DEBUG: org.springframework.web.servlet.DispatcherServlet - DispatcherServlet with name 'spring' processing POST request for [/avispring/login] DEBUG: org.springframework.web.servlet.DispatcherServlet - Testing handler map [org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping@16fffcf] in DispatcherServlet with name 'spring' DEBUG: org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Looking up handler method for path /login DEBUG: org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Did not find handler method for [/login] DEBUG: org.springframework.web.servlet.DispatcherServlet - Testing handler map [org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping@138f01b] in DispatcherServlet with name 'spring' DEBUG: org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping - No handler mapping found for [/login] DEBUG: org.springframework.web.servlet.DispatcherServlet - Testing handler map [org.springframework.web.servlet.handler.SimpleUrlHandlerMapping@1ff154c] in DispatcherServlet with name 'spring' DEBUG: org.springframework.web.servlet.handler.SimpleUrlHandlerMapping - No handler mapping found for [/login] WARN : org.springframework.web.servlet.PageNotFound - No mapping found for HTTP request with URI [/avispring/login] in DispatcherServlet with name 'spring' DEBUG: org.springframework.web.servlet.DispatcherServlet - Cleared thread-bound request context: org.apache.catalina.connector.RequestFacade@c8b445 DEBUG: org.springframework.web.servlet.DispatcherServlet - Successfully completed request DEBUG: org.springframework.web.context.support.XmlWebApplicationContext - Publishing event in WebApplicationContext for namespace 'spring-servlet': ServletRequestHandledEvent: url=[/avispring/login]; client=[0:0:0:0:0:0:0:1]; method=[POST]; servlet=[spring]; session=[BC0FB7E62DC0AFABD8EF72B8BF1CED54]; user=[null]; time=[3ms]; status=[OK] DEBUG: org.springframework.web.context.support.XmlWebApplicationContext - Publishing event in Root WebApplicationContext: ServletRequestHandledEvent: url=[/avispring/login]; client=[0:0:0:0:0:0:0:1]; method=[POST]; servlet=[spring]; session=[BC0FB7E62DC0AFABD8EF72B8BF1CED54]; user=[null]; time=[3ms]; status=[OK] DEBUG: org.springframework.web.servlet.DispatcherServlet - Bound request context to thread: org.apache.catalina.core.ApplicationHttpRequest@bb82df DEBUG: org.springframework.web.servlet.DispatcherServlet - DispatcherServlet with name 'spring' processing POST request for [/avispring/404.html] DEBUG: org.springframework.web.servlet.DispatcherServlet - Testing handler map [org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping@16fffcf] in DispatcherServlet with name 'spring' DEBUG: org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Looking up handler method for path /404.html DEBUG: org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Found 1 matching mapping(s) for [/404.html] : [{[/404.html]}] DEBUG: org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Returning handler method [public org.springframework.web.servlet.ModelAndView com.avispring.controllers.HelloController.errorPage()] DEBUG: org.springframework.web.servlet.DispatcherServlet - Testing handler adapter [org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter@511db5] DEBUG: org.springframework.web.servlet.DispatcherServlet - Testing handler adapter [org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter@1a86ee] DEBUG: org.springframework.web.servlet.DispatcherServlet - Testing handler adapter [org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter@c26a5f] DEBUG: org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod - Invoking [HelloController.errorPage] method with arguments [] DEBUG: org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod - Method [errorPage] returned [ModelAndView: reference to view with name '/404'; model is null] DEBUG: org.springframework.web.servlet.DispatcherServlet - Rendering view [org.springframework.web.servlet.view.JstlView: name '/404'; URL [/WEB-INF/jsp//404.jsp]] in DispatcherServlet with name 'spring' DEBUG: org.springframework.web.servlet.view.JstlView - Rendering view with name '/404' with model {} and static attributes {} DEBUG: org.springframework.web.servlet.view.JstlView - Forwarding to resource [/WEB-INF/jsp//404.jsp] in InternalResourceView '/404' DEBUG: org.springframework.web.servlet.DispatcherServlet - Cleared thread-bound request context: org.apache.catalina.core.ApplicationHttpRequest@bb82df DEBUG: org.springframework.web.servlet.DispatcherServlet - Successfully completed request DEBUG: org.springframework.web.context.support.XmlWebApplicationContext - Publishing event in WebApplicationContext for namespace 'spring-servlet': ServletRequestHandledEvent: url=[/avispring/404.html]; client=[0:0:0:0:0:0:0:1]; method=[POST]; servlet=[spring]; session=[BC0FB7E62DC0AFABD8EF72B8BF1CED54]; user=[null]; time=[1ms]; status=[OK] DEBUG: org.springframework.web.context.support.XmlWebApplicationContext - Publishing event in Root WebApplicationContext: ServletRequestHandledEvent: url=[/avispring/404.html]; client=[0:0:0:0:0:0:0:1]; method=[POST]; servlet=[spring]; session=[BC0FB7E62DC0AFABD8EF72B8BF1CED54]; user=[null]; time=[1ms]; status=[OK]

org.apache.catalina.connector.RequestFacade@c8b445 DEBUG: org.springframework.web.servlet.DispatcherServlet - 成功完成的请求 DEBUG: org.springframework.web.context.support.XmlWebApplicationContext - WebApplicationContext 中命名空间“spring-servlet”的发布事件': ServletRequestHandledEvent: url=[/avispring/login]; 客户=[0:0:0:0:0:0:0:1]; 方法=[POST];servlet=[弹簧];会话=[BC0FB7E62DC0AFABD8EF72B8BF1CED54];用户=[空];时间=[3ms]; status=[OK] DEBUG: org.springframework.web.context.support.XmlWebApplicationContext - Root WebApplicationContext 中的发布事件:ServletRequestHandledEvent: url=[/avispring/login]; 客户=[0:0:0:0:0:0:0:1]; 方法=[POST];servlet=[弹簧];会话=[BC0FB7E62DC0AFABD8EF72B8BF1CED54];用户=[空];时间=[3ms]; status=[OK] 调试:org.springframework.web.servlet。method.annotation.ServletInvocableHandlerMethod - 方法 [errorPage] 返回 [ModelAndView: 对名称为“/404”的视图的引用;模型为空] 调试:org.springframework.web.servlet.DispatcherServlet - 渲染视图 [org.springframework.web.servlet.view.JstlView: name '/404'; URL [/WEB-INF/jsp//404.jsp]] 在 DispatcherServlet 中,名称为“spring”调试:org.springframework.web.servlet.view.JstlView - 使用模型 {} 和静态呈现名称为“/404”的视图属性 {} 调试:org.springframework.web.servlet.view.JstlView - 转发到 InternalResourceView '/404' 中的资源 [/WEB-INF/jsp//404.jsp] 调试:org.springframework.web.servlet.DispatcherServlet - 清除线程绑定请求上下文:org.apache.catalina.core.ApplicationHttpRequest@bb82df 调试:org.springframework.web.servlet。DispatcherServlet - 成功完成请求调试:org.springframework.web.context.support.XmlWebApplicationContext - WebApplicationContext 中命名空间“spring-servlet”的发布事件:ServletRequestHandledEvent: url=[/avispring/404.html]; 客户=[0:0:0:0:0:0:0:1]; 方法=[POST];servlet=[弹簧];会话=[BC0FB7E62DC0AFABD8EF72B8BF1CED54];用户=[空];时间=[1ms]; status=[OK] DEBUG: org.springframework.web.context.support.XmlWebApplicationContext - Root WebApplicationContext 中的发布事件:ServletRequestHandledEvent: url=[/avispring/404.html]; 客户=[0:0:0:0:0:0:0:1]; 方法=[POST];servlet=[弹簧];会话=[BC0FB7E62DC0AFABD8EF72B8BF1CED54];用户=[空];时间=[1ms]; 状态=[确定] XmlWebApplicationContext - 在 WebApplicationContext 中为命名空间“spring-servlet”发布事件:ServletRequestHandledEvent: url=[/avispring/404.html]; 客户=[0:0:0:0:0:0:0:1]; 方法=[POST];servlet=[弹簧];会话=[BC0FB7E62DC0AFABD8EF72B8BF1CED54];用户=[空];时间=[1ms]; status=[OK] DEBUG: org.springframework.web.context.support.XmlWebApplicationContext - Root WebApplicationContext 中的发布事件:ServletRequestHandledEvent: url=[/avispring/404.html]; 客户=[0:0:0:0:0:0:0:1]; 方法=[POST];servlet=[弹簧];会话=[BC0FB7E62DC0AFABD8EF72B8BF1CED54];用户=[空];时间=[1ms]; 状态=[确定] XmlWebApplicationContext - 在 WebApplicationContext 中为命名空间“spring-servlet”发布事件:ServletRequestHandledEvent: url=[/avispring/404.html]; 客户=[0:0:0:0:0:0:0:1]; 方法=[POST];servlet=[弹簧];会话=[BC0FB7E62DC0AFABD8EF72B8BF1CED54];用户=[空];时间=[1ms]; status=[OK] DEBUG: org.springframework.web.context.support.XmlWebApplicationContext - Root WebApplicationContext 中的发布事件:ServletRequestHandledEvent: url=[/avispring/404.html]; 客户=[0:0:0:0:0:0:0:1]; 方法=[POST];servlet=[弹簧];会话=[BC0FB7E62DC0AFABD8EF72B8BF1CED54];用户=[空];时间=[1ms]; 状态=[确定] 时间=[1ms]; status=[OK] DEBUG: org.springframework.web.context.support.XmlWebApplicationContext - Root WebApplicationContext 中的发布事件:ServletRequestHandledEvent: url=[/avispring/404.html]; 客户=[0:0:0:0:0:0:0:1]; 方法=[POST];servlet=[弹簧];会话=[BC0FB7E62DC0AFABD8EF72B8BF1CED54];用户=[空];时间=[1ms]; 状态=[确定] 时间=[1ms]; status=[OK] DEBUG: org.springframework.web.context.support.XmlWebApplicationContext - Root WebApplicationContext 中的发布事件:ServletRequestHandledEvent: url=[/avispring/404.html]; 客户=[0:0:0:0:0:0:0:1]; 方法=[POST];servlet=[弹簧];会话=[BC0FB7E62DC0AFABD8EF72B8BF1CED54];用户=[空];时间=[1ms]; 状态=[确定]

采纳答案by Abhisek Lamsal

Ok that was so frustrating and I have found my answer by hit and trial. To all others who are facing my problem I am posting my solution. I had to change only one line in my web.xml file. I had to replace this code

好吧,这太令人沮丧了,我通过反复试验找到了答案。对于所有面临我的问题的其他人,我正在发布我的解决方案。我只需要更改 web.xml 文件中的一行。我不得不替换此代码

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

with this code

用这个代码

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

and I don't even need this line in spring-security.xml file

我什至不需要 spring-security.xml 文件中的这一行

<security:intercept-url pattern="/j_spring_security_check" access="permitAll"/>

Hope that might help somebody. Happy coding...

希望这可以帮助某人。快乐编码...

回答by Jeff Morin

Did you try setting the login-processing-urlattribute of your <security:form-login>element? I use the same up-to-date versions of Spring and Spring Security as you and I added the login-processing-urlattribute as follows:

您是否尝试设置元素的login-processing-url属性<security:form-login>?我使用与您相同的 Spring 和 Spring Security 的最新版本,并添加了login-processing-url如下属性:

login-processing-url="/j_spring_security_check"

Everything works properly, and I don't even need the following element:

一切正常,我什至不需要以下元素:

<security:intercept-url pattern="/j_spring_security_check" access="permitAll"/>

Of course, if you wish to use /logininstead of /j_spring_security_check, you are free to do so. Just make sure the URIs you put in your JSP and in your Spring Security configuration file match.

当然,如果您想使用/login代替/j_spring_security_check,您可以随意使用。只需确保您放入 JSP 和 Spring Security 配置文件中的 URI 匹配。

Hope this will help...

希望这会有所帮助...

Jeff

杰夫

------------ UPDATE ------------

- - - - - - 更新 - - - - - -

I think about it... Spring Security introduced Cross-Site Request Forgery (CSRF) protection in version 4. When I updated my code, in order to avoid adding CSRF management in all my protected JSPs (not necessary for my business needs), I had to add the following element in my <security:http>element:

我想了想... Spring Security 在版本 4 中引入了跨站请求伪造(CSRF)保护。当我更新我的代码时,为了避免在我所有受保护的 JSP 中添加 CSRF 管理(对于我的业务需求来说不是必需的),我必须在我的<security:http>元素中添加以下元素:

<security:csrf disabled="true"/>

Please give it a try and tell me whether it worked.

请试一试,然后告诉我它是否有效。