Spring安全登录失败错误重定向且无错误消息
我正在尝试构建一个简单的登录表单(JS)并使用Spring安全性。据我所知,当登录失败时,它应该重定向到登录页面(或者只针对bootstrap项目内的JSP登录页面?),但它无法做到这一点。 查询错误字符串参数也为空 我的spring安全配置:Spring安全登录失败错误重定向且无错误消息,spring,spring-security,Spring,Spring Security,我正在尝试构建一个简单的登录表单(JS)并使用Spring安全性。据我所知,当登录失败时,它应该重定向到登录页面(或者只针对bootstrap项目内的JSP登录页面?),但它无法做到这一点。 查询错误字符串参数也为空 我的spring安全配置: @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configu
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.cors()
.and()
.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin()
.defaultSuccessUrl("/", true)
.permitAll()
.and()
.httpBasic()
.and()
.csrf().disable()
.logout()
.permitAll()
.logoutSuccessUrl("/");
}
@Bean
public CorsConfigurationSource corsConfigurationSource() {
final CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(ImmutableList.of("*"));
configuration.setAllowedMethods(ImmutableList.of("HEAD",
"GET", "POST", "PUT", "DELETE", "PATCH"));
configuration.setAllowCredentials(true);
configuration.setAllowedHeaders(ImmutableList.of("Authorization", "Cache-Control", "Content-Type"));
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
@Bean
public UserDetailsService userDetailsService() {
// ensure the passwords are encoded properly
User.UserBuilder users = User.withDefaultPasswordEncoder();
InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
manager.createUser(users.username("user").password("user").roles("USER").build());
manager.createUser(users.username("admin").password("admin").roles("USER","ADMIN").build());
return manager;
}
}
启动:
我正在从JS应用程序向http://localhost:8080/login
,我认为这在本例中无关紧要,但我使用的是MithrilJS请求:
m.request({
method: "POST",
url: "http://localhost:8080/login",
body: {username: login, password: pass}
})
.then((result) => {
UserLogin.loggedIn = true;
})
.catch(error => {
console.log(error);
});
我得到的答复(2个出于某种原因):
现在有趣的是,响应包含html(注意,我的代码中没有这个html):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="description" content="">
<meta name="author" content="">
<title>Please sign in</title>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M" crossorigin="anonymous">
<link href="https://getbootstrap.com/docs/4.0/examples/signin/signin.css" rel="stylesheet" crossorigin="anonymous"/>
</head>
<body>
<div class="container">
<form class="form-signin" method="post" action="/login">
<h2 class="form-signin-heading">Please sign in</h2>
<div class="alert alert-danger" role="alert">Invalid credentials</div> <p>
<label for="username" class="sr-only">Username</label>
<input type="text" id="username" name="username" class="form-control" placeholder="Username" required autofocus>
</p>
<p>
<label for="password" class="sr-only">Password</label>
<input type="password" id="password" name="password" class="form-control" placeholder="Password" required>
</p>
<button class="btn btn-lg btn-primary btn-block" type="submit">Sign in</button>
</form>
</body></html>
请登录
请登录
无效凭证
用户名
密码
登录
知道我在哪里失败了吗
编辑:
谢谢你的回答,虽然它并没有完全回答我的想法,但它确实把我引向了正确的方向
我的主要问题是我有两个独立的项目:1)spring启动项目2)JS应用程序。JS应用程序本身包含表单html(本例中为JS),因为我不希望任何前端代码是或来自后端(SpringBoot项目),而所有登录逻辑都在SpringBootSpringSecurity中
如果我禁用formLogin(我必须这么做,不使用spring登录表单),我就不会得到/login端点
总而言之,我希望在绕过spring登录表单的同时使用spring安全性(这样后端包含登录逻辑,可以通过任何表单访问,或者这就是想法)
虽然我还没有完全到达那里,但我正在到达那里
对于任何好奇的人来说,这是一篇有帮助的文章:HTML是默认的登录表单 为什么定义formLogin() 您必须在授权标头而不是正文中发送用户名和密码 从
HTML是默认的登录表单 为什么定义formLogin() 您必须在授权标头而不是正文中发送用户名和密码 从
您正在尝试使用ajax进行身份验证,因此无法重定向到依赖于服务器响应的任何其他页面,您应该在JS中执行此操作(例如
window.location.href
)
现在,让我们谈谈您案例中的表单登录
。根据您的配置启用UsernamePasswordAuthenticationFilter
.formLogin()
.defaultSuccessUrl("/", true)
.permitAll()
此筛选器将从请求参数获取用户名和密码
protected String obtainUsername(HttpServletRequest request) {
return request.getParameter(usernameParameter);
}
protected String obtainPassword(HttpServletRequest request) {
return request.getParameter(passwordParameter);
}
但是您正试图向服务器发送json正文,因此它无法获得正确的凭据。您应该将其更改为表单
请求
下一个是关于失败重定向url,现在您应该知道ajax不能重定向到其他页面,您配置中的默认failureHandler
将错误地重定向到登录页面,现在您使用的是ajax,因此您只需获取HTML,我想您可以根据标题验证请求(例如401),这里有一个例子
.formLogin()
.failureHandler(new SimpleUrlAuthenticationFailureHandler())
以下是SimpleRuthenticationFailureHandler
if (defaultFailureUrl == null) {
logger.debug("No failure URL set, sending 401 Unauthorized error");
response.sendError(HttpStatus.UNAUTHORIZED.value(),
HttpStatus.UNAUTHORIZED.getReasonPhrase());
}
您可以根据标题和正文获得结果
现在我想您应该知道,您的配置中的defaultSuccessUrl
不会像您预期的那样工作。您需要实现自己的AuthenticationSuccessHandler
最后一个是关于您的
表单
身份验证,表单身份验证大部分是基于cookie的,我认为您所有的请求都应该包含成功登录后发送到服务器的cookie。也许你可以改为研究。你正在尝试使用ajax进行身份验证,因此你不能重定向到依赖于服务器响应的任何其他页面,你应该在JS中这样做(例如window.location.href
)
现在,让我们谈谈您案例中的表单登录
。根据您的配置启用UsernamePasswordAuthenticationFilter
.formLogin()
.defaultSuccessUrl("/", true)
.permitAll()
此筛选器将从请求参数获取用户名和密码
protected String obtainUsername(HttpServletRequest request) {
return request.getParameter(usernameParameter);
}
protected String obtainPassword(HttpServletRequest request) {
return request.getParameter(passwordParameter);
}
但是您正试图向服务器发送json正文,因此它无法获得正确的凭据。您应该将其更改为表单
请求
下一个是关于失败重定向url,现在您应该知道ajax不能重定向到其他页面,您配置中的默认failureHandler
将错误地重定向到登录页面,现在您使用的是ajax,因此您只需获取HTML,我想您可以根据标题验证请求(例如401),这里有一个例子
.formLogin()
.failureHandler(new SimpleUrlAuthenticationFailureHandler())
以下是SimpleRuthenticationFailureHandler
if (defaultFailureUrl == null) {
logger.debug("No failure URL set, sending 401 Unauthorized error");
response.sendError(HttpStatus.UNAUTHORIZED.value(),
HttpStatus.UNAUTHORIZED.getReasonPhrase());
}
您可以根据标题和正文获得结果
现在我想您应该知道,您的配置中的defaultSuccessUrl
不会像您预期的那样工作。您需要实现自己的AuthenticationSuccessHandler
最后一个是关于您的表单
身份验证,表单身份验证大部分是基于cookie的,我认为您所有的请求都应该包含成功登录后发送到服务器的cookie。也许你可以研究一下