使用 Spring Security 登录:不支持请求方法“POST”
Posted
技术标签:
【中文标题】使用 Spring Security 登录:不支持请求方法“POST”【英文标题】:Login with Spring Security : Request method 'POST' not supported 【发布时间】:2015-07-07 14:00:29 【问题描述】:我在使用 Spring Security 登录时遇到问题。登录页面显示正常,但每当我想实际登录时,都会出现以下错误:
Etat HTTP 405 - 不支持请求方法“POST”。
由于我使用的是 Spring Security 4.0.1,请注意表单操作中使用的 /login 引用了 Spring Security 的内置身份验证引擎。因此它与控制器中登录方法中的/login不同。
以下是相关文件:
login.jsp:
<body onload='document.loginForm.username.focus();'>
<h1>Spring Security Custom Login Form (Annotation)</h1>
<div id="login-box">
<h2>Login with Username and Password</h2>
<c:if test="$not empty error">
<div class="error">$error</div>
</c:if>
<c:if test="$not empty msg">
<div class="msg">$msg</div>
</c:if>
<form name='loginForm'
action="<c:url value='/login' />" method='POST'>
<table>
<tr>
<td>User:</td>
<td><input type='text' name='username' value=''></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>
</table>
<input type="hidden"
name="$_csrf.parameterName" value="$_csrf.token" />
</form>
</div>
主控制器:
@Controller
public class MainController
private static final Logger logger = LoggerFactory.getLogger(MainController.class);
@RequestMapping(value = "/login", method=RequestMethod.GET)
public ModelAndView login(
@RequestParam(value="erreur",required = false) String erreur,
@RequestParam(value="logout",required = false) String logout)
ModelAndView model = new ModelAndView();
if(erreur != null)
model.addObject("erreur", "Identifiants incorrectes");
if(logout != null)
model.addObject("msg","you have been logged out successfully");
return model;
@RequestMapping(value = "/admin**", method = RequestMethod.GET)
public String admin(Locale locale, Model model)
logger.info("Bienvenue ! vous êtes en .", locale);
Date date = new Date();
DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);
String formattedDate = dateFormat.format(date);
model.addAttribute("serverTime", formattedDate );
return "admin";
@RequestMapping(value = "/403", method = RequestMethod.GET)
public ModelAndView accesssDenied()
ModelAndView model = new ModelAndView();
//verifier si l'utilisateur est connecté
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
logger.info("Authentification:"+auth);
if (!(auth instanceof AnonymousAuthenticationToken))
UserDetails userDetail = (UserDetails) auth.getPrincipal();
model.addObject("username", userDetail.getUsername());
model.setViewName("403");
return model;
@RequestMapping(value = "/","/index", method = RequestMethod.GET)
public String home(Locale locale, Model model)
logger.info("Bienvenue ! vous êtes en .", locale);
Date date = new Date();
DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);
String formattedDate = dateFormat.format(date);
model.addAttribute("serverTime", formattedDate );
return "index";
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.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd">
<http auto-config="true" use-expressions="true">
<access-denied-handler error-page="/403" />
<intercept-url pattern="/admin**" access="hasRole('admin')" />
<form-login
login-page="/login"
default-target-url="/index"
authentication-failure-url="/login?error"
username-parameter="username"
password-parameter="password" />
<logout logout-success-url="/login?logout" invalidate-session="true"/>
<!-- enable csrf protection -->
<csrf/>
</http>
<authentication-manager>
<authentication-provider>
<jdbc-user-service data-source-ref="dataSource"
users-by-username-query=
"select login,pwd, enabled from utilisateur where login=?"
authorities-by-username-query=
"select login, role from role where login =?" />
</authentication-provider>
</authentication-manager>
</beans:beans>
【问题讨论】:
所有MainController
处理方法都映射到method=RequestMethod.GET
。
【参考方案1】:
您正在对服务进行POST
调用,该服务公开为GET
。
@RequestMapping(value = "/login", method=RequestMethod.GET)
<form name='loginForm'
action="<c:url value='/login' />" method='POST'>
这就是你收到这个的原因。
【讨论】:
我正在使用 Spring security 4,据我了解,它使用 url /login 而不是之前的 /j_security_login_check 和 POST 进行身份验证用户。这通常会给我以下结构: - /login 和 GET :调用控制器以显示登录页面。 -/login with POST : 调用 spring 安全认证机制。【参考方案2】:我刚刚发现了问题所在,在登录 JSP 中我使用表达式语言来评估 csrf 参数名称和令牌,我只是忘记在登录页面中添加 <%@ page isELIgnored="false"%>
属性。
【讨论】:
以上是关于使用 Spring Security 登录:不支持请求方法“POST”的主要内容,如果未能解决你的问题,请参考以下文章
错误 405 请求方法 'POST' 不支持 Spring Security
如何配置 Spring Boot 和 Spring Security 以支持表单登录和 Google OAuth2 登录