一文搞懂SpringSecurity—[Day03]自定义登录逻辑+自定义登录页面
当 进 行 自 定 义 登 录 逻 辑 时 需 要 用 到 之 前 讲 解 的 UserDetailsService
和 PasswordEncoder
。但是
Spring Securit要求:当进行自定义登录逻辑时容器内必须有 PasswordEncoder 实例。所以不能直接 new 对象。
编写配置类
``
@Configuration
public class SecurityConfig {
@Bean
public PasswordEncoder getPw(){
return new BCryptPasswordEncoder();
}
}
自定义逻辑
在 Spring Security
中实现 UserDetailService
就表示为用户详情服务。在这个类中编写用户认证逻辑。
``
/**
* 自定义登录逻辑
*
* @author 爪哇小白2021
* @date 2022/06/30
*/
@Service
public class UserServiceImpl implements UserDetailsService {
@Autowired
private PasswordEncoder pw;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
/**
* 查询数据库判断用户名是否存在,如果不存在抛出UsernameNotFoundException异常
* 为了简单直接模拟数据
*/
if (!"admin".equals(username)){
throw new UsernameNotFoundException("用户名不存在");
}
/**
* 把查询出来的密码(注册时已经加密过)进行解析,或直接把密码放入构造方法中
*/
String password = pw.encode("123");
return new User(username,password,
AuthorityUtils.commaSeparatedStringToAuthorityList("admin,normal"));
}
}
查看效果
重启项目后,在浏览器中输入账号:admin,密码:123。后可以正确进入到 login.html 页面。
自定义登录页面
自定义登录页面
虽然 Spring Security
给我们提供了登录页面,但是对于实际项目中,大多喜欢使用自己的登录页面。所以 Spring Security 中不仅仅提供了登录页面,还支持用户自定义登录页面。实现过程也比较简单,只需要修改配置类即可。
编写登录页面
login.html
``
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="/login" method="post">
用户名:<input type="text" name="username" /><br/>
密码:<input type="password" name="password" /><br/>
<input type="submit" value="登录" />
</form>
</body>
</html>
修改配置类
修改配置类中主要是设置哪个页面是登录页面。
配置类需要继承
WebSecurityConfigurerAdapte
,并重写configure
方法。
- successForwardUrl() :登录成功后跳转地址
- loginPage() :登录页面
- loginProcessingUrl :登录页面表单提交地址,此地址可以不真实存在。
- antMatchers() :匹配内容
- permitAll() :允许
``
package com.example.spring.config;
import com.example.spring.service.impl.UserServiceImpl;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer;
import org.springframework.security.config.annotation.web.configurers.FormLoginConfigurer;
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.web.SecurityFilterChain;
/**
* 安全配置
*
* @author 爪哇小白2021
* @date 2022/06/30
*/
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
//表单提交
http.formLogin()
//自定义登录页面
.loginPage("/login.html")
//当发现/login时认为是登录,必须和表单提交的地址一样。去执行UserServiceImpl
.loginProcessingUrl("/login")
//登录成功后跳转页面,POST请求
.successForwardUrl("/toMain");
http.authorizeRequests()
//login.html不需要被认证
.antMatchers("/login.html").permitAll()
//所有请求都必须被认证,必须登录后被访问
.anyRequest().authenticated();
//关闭csrf防护
http.csrf().disable();
}
@Bean
public PasswordEncoder getPw(){
return new BCryptPasswordEncoder();
}
}
编写控制器
``
package com.example.spring.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* 你好控制器
*
* @author 爪哇小白2021
* @date 2022/06/30
*/
@Controller
public class HelloController {
@GetMapping("/hello")
public String hello() {
return "你好 爪哇小白2021";
}
/**
* 成功后跳转页面
* @return
*/
@RequestMapping("/toMain")
public String toMain(){
return "redirect:/main.html";
}
}
页面展示
p1
p2 登录之后跳转
ps: WebSecurityConfigurerAdapter目前已经是弃用,但是仍然配置有效。
新的实现方式大抵如下