简体   繁体   English

春季安全定制登录表单

[英]spring security custom login form

I'm trying to follow an example for Spring Security with custom login with some customization of my own. 我正在尝试通过自定义登录和我自己的自定义来使用Spring Security的示例。 Not sure where I'm making the mistake, but I'm unable to figure out why the custom form login is not working. 不知道我在哪里出错,但是我无法弄清楚为什么自定义表单登录无法正常工作。 The page is redirected to the protected resource without authentication. 该页面无需身份验证即被重定向到受保护的资源。

The project uses spring-data-jpa to get the data to display in the view. 该项目使用spring-data-jpa来获取要显示在视图中的数据。

web.xml 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" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
  <display-name>spring-security2</display-name>

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

  <!-- The front controller of this Spring Web application, responsible for handling all application requests -->
    <servlet>
        <servlet-name>springDispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>WEB-INF/spring/dispatcher-servlet.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <!-- Map all requests to the DispatcherServlet for handling -->
    <servlet-mapping>
        <servlet-name>springDispatcherServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <!-- needed for ContextLoaderListener -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>WEB-INF/spring/security-context.xml</param-value>
    </context-param>

    <!-- Bootstraps the root web application context before servlet initialization -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
</web-app>

dispatcher-servlet.xml dispatcher-servlet.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">


    <context:component-scan base-package="domain.app"/>
    <mvc:annotation-driven/>

    <bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
        <property name="prefix" value="/WEB-INF/view/jsp/"/>
        <property name="suffix" value=".jsp"/>
    </bean>

    <mvc:resources location="/resources/" mapping="/resources/**"/>

</beans>

security-context.xml security-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:security="http://www.springframework.org/schema/security"
    xsi:schemaLocation="http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-4.2.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <security:http auto-config="true" use-expressions="false" >
        <security:form-login 
            login-page="/login" 
            login-processing-url="/login" 
            username-parameter="custom_username" 
            password-parameter="custom_password"
            authentication-failure-url="/login?error=true"/>
        <security:intercept-url pattern="/films/*" access="ROLE_USER"/>
        <security:intercept-url pattern="/login/*" access="ROLE_ANONYMOUS, ROLE_USER"/>
    </security:http>

    <security:authentication-manager>
        <security:authentication-provider>
            <security:user-service>
                <security:user name="admin" password="password" authorities="ROLE_USER"/>
            </security:user-service>
        </security:authentication-provider>
    </security:authentication-manager>
</beans>

Controller 控制者

@Controller
public class FilmController {

    @Autowired
    private FilmRepository repository;

    @RequestMapping("/")
    public String  film(Model model) {
        model.addAttribute("films", repository.findAll());
        return "film";
    }

    @RequestMapping("/films")
    public String  popularFilms(Model model) {
        model.addAttribute("films", repository.findByCategory("Popular"));
        return "films";
    }

    @RequestMapping(value="/login", method=RequestMethod.GET)
    public String login() {
        return "login";
    }
}

login.jsp login.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>

<link rel="stylesheet"
    href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">

</head>
<body>

    <c:url value="/login" var="loginVar" />
    <form action="${loginVar}" method="post">
        <div class="form-group">
            <label for="username">Email address</label> 
            <input type="text" class="form-control" name="custom_username"
                placeholder="username">
        </div>
        <div class="form-group">
            <label for="password">Password</label> <input
                type="password" class="form-control" name="custom_password"
                placeholder="Password">
        </div>

        <c:if test="${param.error != null}">
            <span class="label label-danger">Invalid username or password</span>
        </c:if>
        <button type="submit" class="btn btn-default">Submit</button>
    </form>

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>


</body>
</html>

You don't have RequestMapping with to handle POST to /login but you have specified it has the login-processing-url . 您没有用于处理POST/login RequestMapping ,但已指定它具有login-processing-url

And furthermore try changing 并尝试更改

<security:intercept-url pattern="/login/*" access="ROLE_ANONYMOUS, ROLE_USER"/>

to

<security:intercept-url pattern="/login**" access="ROLE_ANONYMOUS"/>

I've seen this before, and I allways found suspicious the fact of using the same mapping both for login page and login processing url. 我之前已经看到过这一点,并且始终发现对登录页面和登录处理url使用相同的映射的事实感到可疑。 I have not seen any other issue in your config, so I would start trying to change one of those mappings, for example this way: 我在您的配置中没有看到任何其他问题,因此我将开始尝试更改这些映射之一,例如,通过这种方式:

<security:form-login 
            login-page="/login" 
            login-processing-url="/performLogin"
...

If you try this way, remember to change the login form action to point to the new login-processing-url endpoint. 如果尝试这种方式,请记住将登录表单操作更改为指向新的login-processing-url端点。

You have defined 您已经定义

@RequestMapping(value="/login", method=RequestMethod.GET)
public String login() {
    return "login";
}

but login form submit is POST call. 但登录表单提交是POST调用。 So as per logic you have'nt defined any call to handle POST /login 因此,根据逻辑,您尚未定义任何调用来处理POST / login

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM