maven
自定义登录逻辑
package com.leng.springsecurity.service; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.authority.AuthorityUtils; 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.core.userdetails.UsernameNotFoundException; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; /** * 自定义登录逻辑 */ @Service public class UserDetailsServiceImpl implements UserDetailsService { //没有连数据库就自己定义一个密码出来 @Autowired private PasswordEncoder pw; @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { System.out.println("执行了loadUserByUsername方法"); //1.查询数据库判断用户名是否存在,如果不存在就会抛出异常UsernameNotFoundException if(!"admin".equalsIgnoreCase(username)){ throw new UsernameNotFoundException("用户名不存在"); } //2.把查询出来的密码(在存入数据库前已加密)进行解析或者直接把密码存入构造方法 String encode = pw.encode("123"); //参数1:用户名,参数2:密码,参数3:权限 return new User(username,encode, AuthorityUtils.commaSeparatedStringToAuthorityList("admin")); } }
自定义登录页面及失败页面
创建一个SecurityConfig的配置类,当做SpringSecurity配置类
这里有两种返回方式
1.successForwardUrl/failureForwardUrl:正常成功下的登录成功和登录失败返回
2.successHandler/failureHandler:自定义的返回配置,用于前后端分离/跳转外部链接
@Configuration public class SecurityConfig extends WebSecurityConfigurerAdapter { /** * Description: 授权 * date: 2023/1/15 21:10 * * @author: AL * @since JDK 9 */ @Override protected void configure(HttpSecurity http) throws Exception { //表单提交 http.formLogin() //当请求是/login时代表是登录,必须和表单提交的地址一样,去执行UserDetailsServiceImpl .loginProcessingUrl("/login") //自定义登录页面 .loginPage("/login.html") //登录成功后跳转页面,POST的请求 //.successForwardUrl("/toMain") //登录成功后的处理器,不能和successForwardUrl共存(用于前后端分离/跳转外部链接) .successHandler(new MyAuthenticationSuccessHandler("http://www.baidu.com")) //登录失败后跳转页面,POST的请求 //.failureForwardUrl("/toError") //登录失败后的处理器,不能和failureForwardUrl共存(用于前后端分离/跳转外部链接) .failureHandler(new MyAuthenticationFailureHandler("/error.html")); //手动授权认证 http.authorizeRequests() .antMatchers("/error.html").permitAll() //login.html不需要认证 .antMatchers("/login.html").permitAll() //所有请求必须被认证,必须要登录后执行 .anyRequest().authenticated(); //关闭csrf防护,可以简单理解为是一个防火墙 http.csrf().disable(); } //代表一个实例 @Bean public PasswordEncoder getPW() { return new BCryptPasswordEncoder(); } }
自定义登录成功处理器
package com.leng.springsecurity.handle; import org.springframework.security.core.Authentication; import org.springframework.security.core.userdetails.User; import org.springframework.security.web.authentication.AuthenticationSuccessHandler; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; /** * Description: 登录成功处理器 * date: 2023/1/18 9:17 * * @author: AL * @since JDK 9 */ public class MyAuthenticationSuccessHandler implements AuthenticationSuccessHandler { private String url; public MyAuthenticationSuccessHandler(String url) { this.url = url; } @Override public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException { User user= (User) authentication.getPrincipal(); System.out.println(user.getUsername()); //出于安全原因密码不回打印出来,为null System.out.println(user.getPassword()); //权限 System.out.println(user.getAuthorities()); httpServletResponse.sendRedirect(url); } }
自定义失败处理器
package com.leng.springsecurity.handle; import org.springframework.security.core.AuthenticationException; import org.springframework.security.web.authentication.AuthenticationFailureHandler; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; /** * Description: 登录失败处理器 * date: 2023/1/18 9:16 * * @author: AL * @since JDK 9 */ public class MyAuthenticationFailureHandler implements AuthenticationFailureHandler { private String url; public MyAuthenticationFailureHandler(String url) { this.url = url; } @Override public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException { httpServletResponse.sendRedirect(url); } }