我有一个配置了spring security的spring boot应用程序。我已经将登录请求重定向到http://localhost:8000
,我在python服务器上运行我的前端。现在,当我尝试将登录发布到我的springboot应用程序时,它不起作用。即使我从邮递员那里尝试,也说405
错误。我怎样才能使这个工作。如果我把它作为html放在同一个项目中但不是来自python服务器或邮递员,它的工作原理是/ login。有什么不同。
“message”:“不支持请求方法'POST'”,“path”:“/ login”
表格数据
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Demo</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<!-- Add page specific code/html START -->
<div class="container">
<h1 th:text="#{welcome.message}"></h1>
<form class="form-signin" name="loginForm" th:action="@{/login}" action="/login" method="POST">
<h2 class="form-signin-heading">Please sign in</h2>
<label for="username" class="sr-only">Email address</label>
<input type="text" name="username" id="username" class="form-control" placeholder="Username" required="required" autofocus="autofocus" />
<label for="password" class="sr-only">Password</label>
<input type="password" name="password" id="password" class="form-control" placeholder="Password" required="required" />
<button class="btn btn-lg btn-primary btn-block" type="submit">Sign in</button>
</form>
</div> <!-- /container -->
</body>
</html>
光子服务器上托管的HTML代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Assessment App</title>
<link href="../css/bootstrap.min.css" rel="stylesheet">
<link href="../css/main.css" rel="stylesheet">
</head>
<body>
<div class="container-fluid">
<div class="panel panel-default main-header">
<div class="panel-body">
<div class ="pull-left">Assessments</div>
</div>
</div>
<div class="row">
<div class="login-container col-md-4 col-md-offset-4 col-sm-10 col-sm-offset-1 col-xs-12 col-xs-offset-0">
<div class="panel panel-login">
<div class="panel-heading">
<div class="panel-title">Sign In</div>
</div>
<div class="panel-body">
<form id="loginform" class="form-horizontal" role="form">
<div class="input-group assessment-input-group">
<span class="input-group-addon"><i class="glyphicon glyphicon-user"></i></span>
<input id="login-username" type="text" class="form-control" name="username" value="" placeholder="Username">
</div>
<div class="input-group assessment-input-group">
<span class="input-group-addon"><i class="glyphicon glyphicon-lock"></i></span>
<input id="login-password" type="password" class="form-control" name="password" placeholder="Password">
</div>
<div class="form-group">
<div class="col-sm-12 controls">
<input class="btn btn-primary" type="submit" value="Login">
</div>
</div>
</form>
<div class="login-form-error-text hidden">Invalid credentials</div>
</div>
</div>
</div>
</div>
</div>
<script src="../javascript/jquery-3.3.1.min.js"></script>
<script src ="../javascript/bootstrap.min.js"></script>
<script src="../javascript/lodash.min.js"></script>
<script src="../javascript/login.js"></script>
</body>
</html>
相应的js
$(document).ready(function () {
$('#loginform').submit(function (event) {
event.preventDefault();
$.ajax({
url : 'http://localhost:8080/j_spring_security_check',
type : 'POST',
contentType : 'application/json',
data : JSON.stringify({ j_username : $('#login-username').val(), j_password : $('#login-password').val() }),
success : function () {
window.location.href = '../html/assessment.html';
},
error : function () {
event.preventDefault();
alert('failed');
}
});
});
$('.form-tab-header').on('click', function () {
$('.login-form-error-text').addClass('hidden');
$('.form-tab-header').removeClass('active');
$(this).addClass('active');
$('.form-horizontal').addClass('hidden');
$('.' + $(this).attr('id') + '-content').removeClass('hidden');
});
});
安全配置
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Value("${ldap.urls}")
private String ldapUrls;
@Value("${ldap.base.dn}")
private String ldapBaseDn;
@Value("${ldap.user.dn.pattern}")
private String ldapUserDnPattern;
@Value("${ldap.enabled}")
private String ldapEnabled;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/login**").permitAll()
.antMatchers("/assessments/**").fullyAuthenticated()
.antMatchers("/").permitAll()
.and()
.formLogin()
//.loginPage("http://htmlcode.s3-website.us-east-2.amazonaws.com")
.loginPage("http://localhost:8000")
.loginProcessingUrl("/j_spring_security_check")
.usernameParameter("j_username")
.passwordParameter("j_password")
//.loginPage("/login")
.failureUrl("/login?error")
.permitAll()
.and()
.logout()
.invalidateHttpSession(true)
.deleteCookies("JSESSIONID")
.permitAll();
}
@Override
public void configure(WebSecurity web) {
web.ignoring().antMatchers("/register");
// .antMatchers("/assessments/**");
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
if(Boolean.parseBoolean(ldapEnabled)) {
auth.ldapAuthentication()
.userDetailsContextMapper(userDetailsContextMapper())
.userDnPatterns(ldapUserDnPattern)
.contextSource()
.url(ldapUrls+ldapBaseDn);
}
}
@Bean
public UserDetailsContextMapper userDetailsContextMapper() {
return new LdapUserDetailsMapper() {
@Override
public UserDetails mapUserFromContext(DirContextOperations ctx, String username, Collection<? extends GrantedAuthority> authorities) {
UserDetails details = super.mapUserFromContext(ctx, username, authorities);
return details;
}
};
}
@Bean
CorsFilter corsFilter() {
CorsFilter filter = new CorsFilter();
return filter;
}
}
您忘记了包含csrf值。这是一种防止跨站点攻击的安全预防机制。您有两种选择作为解决方法:
由于默认情况下启用了csrf,因此启用CSRF时不允许使用POST和PUT Http方法。要禁用它,您应该将其添加到安全配置中
.csrf().disable()
例如,你可以有这样的事情:
http.
.csrf().disable().
authorizeRequests()
.antMatchers("/admin/**").access("hasRole('ROLE_ADMIN')")
.and()
.formLogin().loginPage("/login").failureUrl("/login?error")
.usernameParameter("username").passwordParameter("password")
.and()
.logout().logoutSuccessUrl("/login?logout")
.and()
.exceptionHandling().accessDeniedPage("/403");
2.发送csrf令牌值:
如果您使用登录表单的登录页面,我们需要始终在登录表单中将CSRF令牌作为隐藏参数包含在代码中:
<input
type="hidden"
th:name="${_csrf.parameterName}"
th:value="${_csrf.token}" />
如果你想通过ajax登录,你还应该包括这两个参数:
首先保留一些变量中的值:
<script type="text/javascript">
var csrfParameter = '${_csrf.parameterName}';
var csrfToken = '${_csrf.token}';
</script>
然后包括那些
var jsonParams = {};
jsonParams['parentId'] = 1;
jsonParams[csrfParameter] = csrfToken;
// include other values pass ,user, etc.
$.ajax({
type: 'POST',
cache: false,
url: /login,
data: jsonParams,
dataType = 'json',
contentType = 'application/json',
...
});