今天翻到之前做的spring security的demo,在重新进行postman登录测试的时候,一直不走登录逻辑,而是返回登录的html页面。而因为前端使用Thymelef,在使用页面登录的时候,却发现能够登录成功,始终找不到原因。到最后虽然说解决了,但是解决的方法也很搞笑,即使说出来很丢人,但是也是一个法子。如果大家遇到这个问题,也是希望大家能够少走些弯路。
话不多说,直接上代码。
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true) //开启权限注解,默认是关闭的
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private MySuccessHander mySuccessHander;
@Autowired
private MyFailureHander myFailureHander;
@Autowired
private UserAuthAccessDeniedHandler userAuthAccessDeniedHandler;
@Autowired
private UserLoginFailureHandler userLoginFailureHandler;
/**
* 明文加密
* @param http
* @throws Exception
*/
@Bean
public PasswordEncoder createPwdEncoder(){
return new BCryptPasswordEncoder();
}
/* 加上无响应(不会进行登录) 不要加
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
}*/
/**
* 配置拦截请求资源
* @param http
* @throws Exception
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
/*
//对根目录下的所有子目录进行拦截认证 默认方式 /**
http.authorizeRequests().antMatchers("/**").fullyAuthenticated().and()
.formLogin(); //默认的认证方式,表单认证
// .httpBasic(); //使用浏览器提供的表单
*/
//对根目录下的所有子目录进行拦截认证 默认方式 /**
http.authorizeRequests()
.antMatchers("/static/**").permitAll() //放行静态资源
.antMatchers("/static/script/**").permitAll() //放行静态资源(无效 不知道原因)
.antMatchers("/initialPage","/toSession").permitAll() ///initialPage permitAll() 该initialPage页面下不被拦截(放行)
.antMatchers("/login").permitAll() ///login permitAll() login 登录页不被拦截(放行)
.antMatchers("/toLogin").permitAll() ///toLogin permitAll() toLogin 登录页不被拦截(放行)
// .antMatchers("/static/**").permitAll()
.antMatchers("/regist").permitAll() ///regist permitAll() regist 登录页不被拦截(放行)
.antMatchers(" /favicon.ico").permitAll() //放行 不需要认证
.antMatchers("/**").fullyAuthenticated(); // /** fullyAuthenticated()所有的都被拦截 拦截所有
// .httpBasic(); //使用浏览器提供的表单
http.csrf().disable().cors(); //关闭csrf功能,登出失败可能存在的原因 以及登录失败(不请求action)的原因 并且开启跨域
// http.csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()); springSecurity自动往浏览器写入token
http.formLogin().loginPage("/toLogin"). //默认的认证方式 表单认证 (提交的时候url与loginPage方法中的参数保持一致也可以成功)
// loginProcessingUrl("/login");
loginProcessingUrl("/login"). //提交的时候url与loginProcessingUrl方法中的参数保持一致(成功)
successHandler(mySuccessHander).failureHandler(userLoginFailureHandler);
// .usernameParameter("user").passwordParameter("pwd"); //自定义用户名和密码的参数名
http.logout().logoutSuccessUrl("/toLogin"); //注销功能 logoutSuccessUrl注销成功后默认跳转页面(controller控制器)
// http.sessionManagement().sessionFixation().changeSessionId(); //默认更改JsessionId
// http.sessionManagement().maximumSessions(1).maxSessionsPreventsLogin(true).and().invalidSessionUrl("/toSession");
// http.sessionManagement().maximumSessions(1).maxSessionsPreventsLogin(true).and().invalidSessionUrl("/toSession");
// 并发session控制 一个人用户在一台服务器上同时有多少个session
//maxSessionsPreventsLogin(true) 如果达到了最大session数,不允许新的session数再次登录
//.invalidSessionUrl("/toLogin") session失效后跳转到的url
//配置没有权限自定义处理器
// http.exceptionHandling().accessDeniedHandler(userAuthAccessDeniedHandler);
//记住我功能 cookie默认保存两周
// http.rememberMe().rememberMeParameter("");
}
}
注意到我这里
loginProcessingUrl("/login"). //提交的时候url与loginProcessingUrl方法中的参数保持一致(成功)
登录是的路径是login。 接下来看前端代码
$.ajax({
url: "/login",//请求路径
type: 'post',
data: {
"username": username,//字段和html页面的要对应 id和name一致
"password": password,//字段和html页面的要对应
"_csrf":token,
// "remember-me":remember,
// "imageCode": imageCode
},
注意看到我的请求路径也是login, 用户名及其密码参数名是默认的,我没有修改。分别是username password
接下来,我进行Postman使用post请求登录的时候,
路径没有写错(包括端口号),返回的结果却是我的登录的html页面。
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity5" >
<html lang="en">
<html>
<head>
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<!--<script th:src="@{/static/script/jquery.min.js}"></script>-->
<!--<script th:src="@{/static/script/jquery.min.js}"></script>-->
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript">
function doLogin(){
var url = "/login";
// var url = "/product/add";
// var username= $("#j_username").val();
var username=document.getElementById('j_username').value;
alert(username)
var password=document.getElementById('j_password').value;
alert(password)
var token=document.getElementById('token').value;
alert(token)
/*$.ajax({
url:url,
type:"POST",
async: false,
data:$("#formID").serialize(),
success: function(data){
/!* $("#results").text(data);*!/
alert("====")
}
});*/
$.ajax({
url: "/login",//请求路径
type: 'post',
data: {
"username": username,//字段和html页面的要对应 id和name一致
"password": password,//字段和html页面的要对应
"_csrf":token,
// "remember-me":remember,
// "imageCode": imageCode
},
// type: 'post',
success: function (obj) {
console.log(obj.success)
alert(obj.success)
if(obj.success){
window.location.href="/index"
}else{
window.location.href="/toLogin"
}
// window.location.href="/index" //登录之后跳转到该控制器
// alert("==========")
}
});
}
</script>
<title>登陆界面</title>
</head>
<body>
<h3>欢迎登陆</h3>
<div>
<!-- <form id="formID">-->
<tr><td>用户名:</td><td><input type='text' id='j_username' name="username" value=''></td></tr>
<tr><td>密 码:</td><td><input type='password' name="password" id='j_password'/></td></tr>
<tr><td>token:</td><td><input type='text' name="token" id='token'/></td></tr>
<!-- </form>-->
<tr><td colspan='2'><button name="submit" type="button" onclick="doLogin()" value="登陆">登录</button></td></tr>
</div>
<div id="results"></div>
</body>
<a href="regist">注册用户</a>
</html>
这个就是我的登录的Html页面,他并没有走我在SecurityConfig中配置的登录成功配置类==》successHandler(mySuccessHander);这就很奇怪。注意,我以前postman测试是可以的。
之后也是试了很多遍,难受。最终,我这么试了一下,没有加上用户名及其密码,给我返回没有用户名。
我再加上用户名密码
又可以访问。不得不说,真的是很奇怪。很奇怪。
这辈子坚持与不坚持都不可怕,怕的是独自走在坚持的道路上!!! | |
---|---|
欢迎加入技术群聊!