1 创建一个项目
添加一个配置类:
@Configuration
public class SecurityConfigextends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.formLogin() // 表单登录
.and()
.authorizeRequests() // 认证配置
.anyRequest() // 任何请求
.authenticated(); // 都需要身份验证
}
}
2 运行这个项目 访问 localhost:8080
默认的用户名:user
密码在项目启动的时候在控制台会打印,注意每次启动的时候密码都回发生变化!
输入用户名,密码,这样表示可以访问了,404 表示我们没有这个控制器,但是我们可以 访问了。
package com.atguigu.controller;
@Controller
public class IndexController {
@GetMapping("index")
@ResponseBody
public String index(){
return "success";
}
}
org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFil
ter
org.springframework.security.web.context.SecurityContextPersistenceFilter
org.springframework.security.web.header.HeaderWriterFilter
org.springframework.security.web.csrf.CsrfFilter
org.springframework.security.web.authentication.logout.LogoutFilter
org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter
org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter
org.springframework.security.web.authentication.ui.DefaultLogoutPageGeneratingFilter
org.springframework.security.web.savedrequest.RequestCacheAwareFilter
org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter
org.springframework.security.web.authentication.AnonymousAuthenticationFilter
org.springframework.security.web.session.SessionManagementFilter
org.springframework.security.web.access.ExceptionTranslationFilter
org.springframework.security.web.access.intercept.FilterSecurityInterceptor
代码底层流程:重点看三个过滤器: FilterSecurityInterceptor:是一个方法级的权限过滤器, 基本位于过滤链的最底部
super.beforeInvocation(fi) 表示查看之前的 filter 是否通过。 fi.getChain().doFilter(fi.getRequest(), fi.getResponse());表示真正的调用后台的服务。 ExceptionTranslationFilter:是个异常过滤器,用来处理在认证授权过程中抛出的异常
UsernamePasswordAuthenticationFilter :对/login 的 POST 请求做拦截,校验表单中用户 名,密码
BCryptPasswordEncoder 是 Spring Security 官方推荐的密码解析器,平时多使用这个解析 器。
@Test
public void test01(){
// 创建密码解析器
BCryptPasswordEncoder bCryptPasswordEncoder = new
BCryptPasswordEncoder();
// 对密码进行加密
String atguigu = bCryptPasswordEncoder.encode("atguigu");
// 打印加密之后的数据
System.out.println("加密之后数据:\t"+atguigu);
//判断原字符加密后和加密之前是否匹配
boolean result = bCryptPasswordEncoder.matches("atguigu", atguigu);
// 打印比较结果
System.out.println("比较结果:\t"+result);
}
4、设置登录系统的账号、密码
方式一:在 application.properties
spring.security.user.name=atguigu
spring.security.user.password=atguigu
方式二:编写类实现接口
package com.atguigu.config;
@Configuration
public class SecurityConfig {
// 注入 PasswordEncoder 类到 spring 容器中
@Bean
public PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
}
package com.atguigu.service;
@Service
public class LoginService implements UserDetailsService {
@Override
public UserDetails loadUserByUsername(String username) throws
UsernameNotFoundException {
// 判断用户名是否存在
if (!"admin".equals(username)){
throw new UsernameNotFoundException("用户名不存在!");
// 从数据库中获取的密码 atguigu 的密文
String pwd =
"$2a$10$2R/M6iU3mCZt3ByG7kwYTeeW0w7/UqdeXrb27zkBIizBvAven0/na";
// 第三个参数表示权限
return new User(username,pwd,
AuthorityUtils.commaSeparatedStringToAuthorityList("admin,"));
}
}
com.baomidou
mybatis-plus-boot-starter
3.0.5
mysql
mysql-connector-java
org.projectlombok
lombok
5.3 制作实体类
@Data
public class Users {
private Integer id;
private String username;
private String password;
}
5.4 整合 MybatisPlus 制作 mapper
@Repository
public interface UsersMapper extends BaseMapper {
}
配置文件添加数据库配置
#mysql 数据库连接
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/demo?serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=root
5.5 制作登录实现类
@Service("userDetailsService")
public class MyUserDetailsService implements UserDetailsService {
@Autowired
private UsersMapper usersMapper;
@Override
public UserDetails loadUserByUsername(String s) throws
UsernameNotFoundException {
QueryWrapper wrapper = new QueryWrapper();
wrapper.eq("username",s);
Users users = usersMapper.selectOne(wrapper);
if(users == null) {
throw new UsernameNotFoundException("用户名不存在!");
}
System.out.println(users);
List auths =
AuthorityUtils.commaSeparatedStringToAuthorityList("role");
return new User(users.getUsername(),
new BCryptPasswordEncoder().encode(users.getPassword()),auths);
}
}
5.6 引入前端模板依赖
org.springframework.boot
spring-boot-starter-thymeleaf
5.7 编写控制器
@Controller
public class IndexController {
@GetMapping("index")
public String index(){
return "login";
}
@GetMapping("findAll")
@ResponseBody
public String findAll(){
return "findAll";
}
}
5.8 设置未授权的请求跳转到登录页
@Override
protected void configure(HttpSecurity http) throws Exception {
// 配置认证
http.formLogin()
.loginPage("/index") // 配置哪个 url 为登录页面
.loginProcessingUrl("/login") // 设置哪个是登录的 url。
.successForwardUrl("/success") // 登录成功之后跳转到哪个 url
.failureForwardUrl("/fail");// 登录失败之后跳转到哪个 url
http.authorizeRequests()
.antMatchers("/layui/**","/index") //表示配置请求路径
.permitAll() // 指定 URL 无需保护。
.anyRequest() // 其他请求
.authenticated(); //需要认证
// 关闭 csrf
http.csrf().disable();
}
注意:页面提交方式必须为 post 请求,所以上面的页面不能使用,用户名,密码必须为 username,password
测试: http://localhost:8090/findAll
访问 findAll 进入登录页面
认证完成之后返回登录成功