如何使用自定义登录页面纠正 Spring Security 异常?
Posted
技术标签:
【中文标题】如何使用自定义登录页面纠正 Spring Security 异常?【英文标题】:How to rectify spring security exception with custom login page? 【发布时间】:2017-01-24 08:03:03 【问题描述】:我得到的解释
HTTP 状态 403 - 在请求参数“_csrf”或标头“X-CSRF-TOKEN”上发现无效的 CSRF 令牌“null”。
我正在尝试通过自定义登录页面实现 Spring Security
spring-security.xml
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
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-4.1.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-4.0.xsd">
<!-- <http>
<intercept-url pattern ="/welcome*" access="hasRole('ROLE_USER')"/>
<http-basic/>
</http> -->
<!-- <http>
<intercept-url pattern ="/welcome*" access="hasRole('ROLE_USER')"/>
<form-login/>
<logout logout-success-url="/home"/>
</http> -->
<http>
<intercept-url pattern ="/welcome*" access="hasRole('ROLE_USER')"/>
<form-login login-page="/login" default-target-url="/welcome" authentication-failure-url="/loginfailed"/>
<logout logout-success-url="/logout"/>
</http>
<authentication-manager>
<authentication-provider>
<user-service>
<user name="rahul" password="123" authorities="ROLE_USER"/>
<user name="rohit" password="567" authorities="ROLE_USER"/>
</user-service>
</authentication-provider>
</authentication-manager>
</beans:beans>
login.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!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>Login Page</title>
<!-- <style>
.errorblock
color : #f0000;
background-color : #ffEEEE;
border : 3px solid #ff0000;
padding : 8px;
margin : 16px;
</style> -->
</head>
<body onload='document.f.j_username.focus();' bgcolor="blue">
<h3>Login with Username andPassword (Custom page)</h3>
<%-- <c:if test="$SPRING_SECURITY_LAST_EXCEPTION !=null"">
<div class="errorblock">
Your login atempt are not sucessfull,try again
<br/>Caused : $sessionScope["SPRING_SECURITY_LAST_EXCEPTION"].message
</div>
</c:if> --%>
<%-- <form name='f' action="<c:url value='j_spring_security_logout'/>" method="POST">
--%>
<form name='f' action='/SpringSecurityApplication/login' method="POST">
<table>
<tr>
<td>User :</td><td><input type='text' name='username'></td>
</tr>
<tr>
<td>Password :</td><td><input type='password' name='password'></td>
</tr>
<tr><td colspan ='2'><input name="submit" type="submit" value="submit" ></td></tr>
<tr><td colspan ='2'><input name="reset" type="reset" ></td></tr>
</table>
</form>
</body>
</html>
LoginController.java
package com.springtraining.security.controller;
import java.security.Principal;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@Controller
public class LoginController
public LoginController()
System.out.println("LoginController constructor is called ");
@RequestMapping(value = "/welcome", method = RequestMethod.GET)
public String printWelcome(ModelMap model, Principal principal)
System.out.println("**********Login Controller is Called********");
String name = principal.getName();
model.addAttribute("username", name);
model.addAttribute("message", "Spring Security Custom Form Example");
return "hello";
@RequestMapping(value = "/*", method = RequestMethod.GET)
public String home(ModelMap model)
return "home";
@RequestMapping(value = "/login", method = RequestMethod.GET)
public String login(ModelMap model)
return "login";
@RequestMapping(value = "/logout", method = RequestMethod.GET)
public String logout(ModelMap model)
return "login";
@RequestMapping(value = "/loginfailed", method = RequestMethod.GET)
public String loginError(ModelMap model)
model.addAttribute("error","true");
return "login";
你好.jsp
home.jsp 我觉得不需要
【问题讨论】:
【参考方案1】:您需要在登录时提交 crsf 令牌(以及注销和其他所有 POST、PUT、DELETE 请求)。
有几种方法可以将它添加到您的 jsp:
使用 spring 的 jsp<form:form>
标签(而不是标准表单标签)或
您需要显式添加 crsf 令牌,通过 spring 安全标签 <sec:csrfInput />
或:
通过“标准 jsp”:
“标准jsp”示例:
<input type="hidden"
name="$_csrf.parameterName"
value="$_csrf.token"/>
@see: Spring Security 参考章节18.4.3 Include the CSRF Token
顺便说一句:我强烈建议阅读完整的Chapter 18. Cross Site Request Forgery (CSRF)
【讨论】:
以上是关于如何使用自定义登录页面纠正 Spring Security 异常?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Spring Security 中通过 jdbc 身份验证使用自定义登录页面
如何使用 DaoAuthenticationProvider 向 Spring 应用程序添加一个 REST Angular 自定义登录页面
如何在grails中自定义spring security插件登录页面