在DispatcherServlet中找不到带有URI [/.../j_spring_security_check]的HTTP请求的映射,其名称为“servlet-dispatcher”

时间:2016-01-13 10:46:36

标签: spring spring-mvc spring-security mapping

扑通,

Spring版本: 4.0.2.RELEASE

Spring Security版本: 4.0.2.RELEASE

DB PostgreSQL版本: 9.4-1202-jdbc42

我正在尝试使用spring-security通过安全连接访问我的主页。 当我尝试使用login / password连接时,我遇到了这个错误:

  

警告:找不到带URI的HTTP请求的映射   DispatcherServlet中的[/ web-client-smarteo / j_spring_security_check]   名称为'servlet-dispatcher'

当我提交log / pass时,它会让我:

  

http://localhost:8080/web-client-smarteo/j_spring_security_check?username=alfacamp&password=alfacam&submit=&%24%7B_csrf.parameterName%7D=%24%7B_csrf.token%7D

并显示

  

HTTP 404请求的资源是不可用的

我的样本详情:

更新 web.xml中

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

<!-- Spring Security 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>

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

<servlet>
    <servlet-name>servlet-dispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/dispatcher-servlet.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>servlet-dispatcher</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

调度员servlet.xml中

    <mvc:annotation-driven />
    <context:component-scan base-package="com.smarteo.laugustoni.*" />
[...]
    <bean
        class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix">
            <value>/vues/</value>
        </property>
        <property name="suffix">
            <value>.jsp</value>
        </property>
    </bean>

弹簧的security.xml

<http auto-config="true" use-expressions="true">

    <intercept-url pattern="/welcome**" access="hasRole('CUSTOMER')" />

    <!-- access denied page -->
    <access-denied-handler error-page="/403" />

    <form-login 
        login-page="/connection" 
        default-target-url="/welcome"
        login-processing-url="/j_spring_security_check"
        authentication-failure-url="/connection?error" 
        username-parameter="username"
        password-parameter="password" />
    <logout logout-success-url="/connection?logout"  />
    <!-- enable csrf protection -->
    <csrf/>
</http>

<!-- Select users and user_roles from database -->
<authentication-manager>
  <authentication-provider>
    <jdbc-user-service data-source-ref="dataSource"
      users-by-username-query=
        "select usr_name,usr_password from smarteo_user where usr_name=?"
      authorities-by-username-query=
        "select usr_name, usr_role from smarteo_user where usr_name =?  " />
  </authentication-provider>
</authentication-manager>

ConnectionController.java

package com.smarteo.laugustoni.controller;

import org.springframework.security.authentication.AnonymousAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;

import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

import com.smarteo.laugustoni.services.User.IServiceUser;

@Controller
public class ConnectionController {

    @RequestMapping(value={"/", "/welcome**"}, method = RequestMethod.GET)
    public String defaultPage(ModelMap pModel)
    {
        return "connection";
    }

    @RequestMapping(value="/connexion", method = RequestMethod.GET)
    public ModelAndView connection(
            @RequestParam(value="error", required = false) String error,
            @RequestParam(value = "logout", required = false)String logout)
    {
        ModelAndView model = new ModelAndView();
        if (error != null) {
            model.addObject("error", "Invalid username and password!");
        }

        if (logout != null) {
            model.addObject("msg", "You've been logged out successfully.");
        }
        model.setViewName("connection");

        return model;
    }

感谢您的帮助。

编辑1

connection.jsp

<%@page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<%@taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<%@taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@page session="true"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
  <body>
       <form name="loginForm" action="/j_spring_security_check">
                <!-- TextBox Section -->
                <div class="input-group visible">
                    <spring:message code="connection.label.account"/>
                    <input name="username" path="username" placeholder="Nom du compte" type="text" class="form-control" aria-describedby="basic-addon1"/>
                    <div class="alert alert-danger" role="alert"><form:errors path="username" cssclass="error"/></div>
                </div><br />
                <div class="input-group visible">
                    <spring:message code="connection.label.password"/> 
                    <input name="password" path="password" placeholder="Mot de passe" type="password" class="form-control" aria-describedby="basic-addon1"/><br />
                    <div class="alert alert-danger" role="alert"><form:errors path="password" cssclass="error"/></div>
                </div><br />
                <!-- TextBoxSection -->             

                <!-- Button Section -->
                <button name="submit" type="submit" class="btn btn-default visible">
                    <spring:message code="connection.button.label.connect"/>
                </button><br />
                <!-- Button Section -->

                <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
            </form>
</body>

编辑2:

我现在正在使用:

<form name="loginForm" action="<c:url value='/login' />" method="POST" >

我也改变了我的spring-security.xml:

    <http auto-config="true" use-expressions="true">
    <intercept-url pattern="/welcome**" access="hasRole('CUSTOMER')" />

    <!-- access denied page -->
    <access-denied-handler error-page="/403" />
    <form-login 
        login-page="/login" 
        default-target-url="/welcome**" 
        authentication-failure-url="/login?error" 
        username-parameter="username"
        password-parameter="password" />
    <logout logout-success-url="/login?logout"  />
    <!-- enable csrf protection -->
    <csrf/>
</http>

我的ConnectionController.java

@RequestMapping(value = "/welcome**", method = RequestMethod.GET)
public String defaultPage() 
{
    return "home";
}

@RequestMapping(value = "/login", method = RequestMethod.GET)
public ModelAndView login(
        @RequestParam(value = "error", required = false) String error,
        @RequestParam(value = "logout", required = false) String logout)
{
    ModelAndView model = new ModelAndView();
    if (error != null) {
        model.addObject("error", "Invalid username and password!");
    }

    if (logout != null) {
        model.addObject("msg", "You've been logged out successfully.");
    }
    model.setViewName("connection");

    return model;
}
@RequestMapping(value = "/403", method = RequestMethod.GET)
public ModelAndView accesssDenied() {

  ModelAndView model = new ModelAndView();

  //check if user is login
  Authentication auth = SecurityContextHolder.getContext().getAuthentication();
  if (!(auth instanceof AnonymousAuthenticationToken)) {
    UserDetails userDetail = (UserDetails) auth.getPrincipal(); 
    model.addObject("username", userDetail.getUsername());
  }

  model.setViewName("403");
  return model;

}

我现在正在获取状态HTTP 405 - 当我尝试登录时不支持请求方法'POST'

1 个答案:

答案 0 :(得分:1)

我的问题是由于Spring安全版。 事实上,对于4.x,您必须将csrf放入表单操作中。

使用解决方案修改了我的来源:

connection.jsp

 <form name="loginForm" action="<c:url value='/login?${_csrf.parameterName}=${_csrf.token} }' />" method="POST" >
                    <!-- TextBox Section -->
                    <div class="input-group visible">
                        <spring:message code="connection.label.account"/>
                        <input name="username" path="username" placeholder="Nom du compte" type="text" class="form-control" aria-describedby="basic-addon1"/>
                        <!--<div class="alert alert-danger" role="alert"><form:errors path="username" cssclass="error"/></div>-->
                    </div><br />
                    <div class="input-group visible">
                        <spring:message code="connection.label.password"/> 
                        <input name="password" path="password" placeholder="Mot de passe" type="password" class="form-control" aria-describedby="basic-addon1"/><br />
                        <!--<div class="alert alert-danger" role="alert"><form:errors path="password" cssclass="error"/></div>-->   
                    </div><br />
                    <!-- TextBoxSection -->             

                    <!-- Button Section -->
                    <input name="submit" type="submit" class="btn btn-default visible" value=<spring:message code="connection.button.label.connect"/> />
                    <br />
                    <!-- Button Section -->

                </form>

弹簧security.xml文件:

<http auto-config="true" >
    <intercept-url pattern="/welcome**" access="hasRole('CUSTOMER')" />
    <form-login  login-page="/login" 
            default-target-url="/welcome"
            username-parameter="username" 
            password-parameter="password" 
            authentication-failure-url="/403" />
    <!-- enable csrf protection --> 
    <csrf disabled="true"/>
</http>