项目场景:
输入用户名密码,认证成功之后进行跳转
核心:要理解需要包含的是【点index里面登录跳转到登陆页面的controller 】和 【登陆点sign in跳转到成功页面的controller】,两者不一样
问题描述
在http://localhost:8080/toLogin一直跳转,报重定向次数过多
错误1:把登陆成功跳转和跳转登陆两个搞混了,都设置成了一个
错误2:没有将两个url进行permitAll放行,导致一直登陆转登陆转登陆,一直重定向
原因分析:
必须要保证,跳转成功,去登陆页的url是没有被springsecurity拦截的
http://localhost:8080/:首页
http://localhost:8080/toLogin:输入用户名密码后,点sign in会跳转到/toLogin接口去执行,一般核对用户名和密码逻辑会在这里,认证成功之后会跳转到指定页面接口
http://localhost:8080/toLoginPage:进入未在.requestMatchers("/","/index","等等").permitAll()
中设置的接口页面,都会弹出登陆页面,即在form.loginPage("/toLoginPage")
设置的
.requestMatchers("/","/index").permitAll()
.requestMatchers("/toLogin","/toLoginPage").permitAll()
@RequestMapping ("/toLogin")
public String toLogin(@RequestParam String username,
@RequestParam String pwd){
log.info("前台接收到的用户名为:=========="+username);
log.info("前台接收到的密码为:=========="+pwd);
String login = userService.login(username, pwd);
return "index";
}
//跳转登陆页面的请求
@RequestMapping ("/toLoginPage")
public String toLogin(){
return "views/login";
}
springsecurityConfig完整代码
package com.lkz.config;
import com.lkz.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.ProviderManager;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.provisioning.JdbcUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import javax.sql.DataSource;
@EnableWebSecurity
@Configuration
public class SecurityConfig {
@Autowired
UserDetailsService userDetailsService;
@Bean
public PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
/**
* 配置过滤器链,进行满足要求的放行
* @param httpSecurity
* @return
* @throws Exception
*/
//授权
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception {
//首页所有人都可以访问,功能页只有有权限的人才能访问
httpSecurity
.authorizeHttpRequests((requests) -> requests
.requestMatchers("/","/index").permitAll()
.requestMatchers("/toLogin","/toLoginPage").permitAll()
.requestMatchers("/level1/**","/level2/**","/level3/**").hasRole("root")
.requestMatchers("/level2/**").hasRole("admin")
//对静态资源的过滤
.requestMatchers("/css/**","/js/**","/views/**").permitAll()
.anyRequest().authenticated()
//没有权限默认回到登陆页面,也可以不传参数,默认是login.html页面
).formLogin(form -> form.loginPage("/toLoginPage")
//处理前端跳转页面,要跟form表单里的action相同
.loginProcessingUrl("/toLogin")
.passwordParameter("pwd")
.usernameParameter("username"))
.csrf(csrf -> csrf.disable());
return httpSecurity.build();
}
/**
* AuthenticationManager:负责认证的
* DaoAuthenticationProvider:负责把userDetailsService,passwordEncoder给整合起来送给AuthenticationManager的
* @param userDetailsService
* @param passwordEncoder
* @return
*/
@Bean
public AuthenticationManager authenticationManager(
UserDetailsService userDetailsService,
PasswordEncoder passwordEncoder) {
DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
//关联userDetailsService查询数据方法
authenticationProvider.setUserDetailsService(userDetailsService);
//关联使用的密码编码器
authenticationProvider.setPasswordEncoder(passwordEncoder);
return new ProviderManager(authenticationProvider);
}
}
解决方案:
把loginPage和loginProcessingUrl搞清楚,设置成了不一样的,并且让这两个url都可以permitAll了,保证springsecurity框架不会拦截
).formLogin(form -> form.loginPage("/toLoginPage")
//处理前端跳转页面,要跟form表单里的action相同
.loginProcessingUrl("/toLogin")