用户认证+用户授权
Apache旗下的轻量级权限控制框架
和spring无缝整合 全面的权限控制 专门为web开发而设计 旧版本不能脱离web环境使用 新版本对整个框架进行了分层抽取,分成了核心模块和web模块。单独引入核心模块就可以脱离web环境 重量级
查询数据库用户名和密码过程
*创建类继承UsernamePasswordAuthenticationFilter,重写三个方法
*创建实现类UserDetailService,编写查询数据过程,返回User对象,这个User对象是安全框架提供对象
数据加密接口,用于返回User对象里面密码加密
# 配置端口 server.port=8111 # 配置用户名 spring.security.user.name=atguigu # 配置用户密码 spring.security.user.password=atguigu
package com.example.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter{
/**
* @param auth
* @description :重写方法,设置用户名和密码
* @date : 2023/2/27 10:27
* @author : 09zhj
* @since : JDK 1.8
*/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception{
// 加密
BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
// 调用方法进行加密
String password = passwordEncoder.encode("123");
// 设置用户名和密码
auth.inMemoryAuthentication().withUser("lucy").password(password).roles("admin");
}
// 创建加密接口对象
@Bean
PasswordEncoder password(){
return new BCryptPasswordEncoder();
}
}
3.1第一步 创建配置类,设置使用哪个UserDetailsService实现类
package com.example.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
/**
* @author : 09zhj
* @description :自定义编写实现类设置用户名和密码
* @date : 2023/2/27 12:59
* @since : JDK 1.8
*/
@Configuration
public class SecurityConfigDemo extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService userDetailsService;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception{
auth.userDetailsService(userDetailsService).passwordEncoder(password());
}
// 创建加密接口对象
@Bean
PasswordEncoder password(){
return new BCryptPasswordEncoder();
}
}
3.2第二步 编写实现类,返回User对象,User对象有用户名密码和操作权限
package com.example.service;
import org.springframework.security.core.GrantedAuthority;
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.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import java.util.List;
@Service("userDetailsService")
public class MyUserDetailsService implements UserDetailsService {
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
List auths =
AuthorityUtils.commaSeparatedStringToAuthorityList("role");
return new User("mary",
new BCryptPasswordEncoder().encode("123"),auths);
}
}
1.1 第一步,引入相关依赖
com.baomidou
mybatis-plus-boot-starter
3.5.2
mysql
mysql-connector-java
org.projectlombok
lombok
1.2 第二步,创建数据库和数据库表
CREATE TABLE `users` (
`id` int(11) NOT NULL,
`username` varchar(255) DEFAULT NULL COMMENT '用户名',
`password` varchar(255) DEFAULT NULL COMMENT '用户密码',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
1.3 第三步,创建表对应的实体类
package com.example.entity;
import lombok.Data;
@Data
public class Users {
private Integer id;
private String username;
private String password;
}
1.4 第四步,整合mp,创建接口,继承mp的接口
public interface UsersMapper extends BaseMapper {
}
1.5 第五步,在MyUserDetailsService调用mapper里面的方法查询数据库进行用户认证
package com.example.service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.entity.Users;
import com.example.mapper.UsersMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
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.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import java.util.List;
@Service("userDetailsService")
public class MyUserDetailsService implements UserDetailsService {
@Autowired
private UsersMapper usersMapper;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
// 调用usersMapper方法查询数据库,根据用户名查询数据库
QueryWrapper wrapper = new QueryWrapper<>();
// where username=?
wrapper.eq("username",username);
Users users = usersMapper.selectOne(wrapper);
// 判断进if,数据库没有用户名,认证失败
if (users == null){
throw new UsernameNotFoundException("用户名不存在!");
}
List auths =
AuthorityUtils.commaSeparatedStringToAuthorityList("role");
// 从查询数据库返回users对象,得到用户名和密码,返回
return new User(users.getUsername(),
new BCryptPasswordEncoder().encode(users.getPassword()),auths);
}
}
1.6 第六步,启动类加注解
package com.example;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@MapperScan("com.example.mapper")
public class SpringbootSecurityApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootSecurityApplication.class, args);
}
}
1.7 第七步,配置数据库信息
#mysql数据库连接
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/db1?serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=123456
package com.example.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
/**
* @author : 09zhj
* @description :自定义编写实现类设置用户名和密码
* @date : 2023/2/27 12:59
* @since : JDK 1.8
*/
@Configuration
public class SecurityConfigDemo extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService userDetailsService;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception{
auth.userDetailsService(userDetailsService).passwordEncoder(password());
}
// 创建加密接口对象
@Bean
PasswordEncoder password(){
return new BCryptPasswordEncoder();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.formLogin() //自定义自己编写的登陆页面
.loginPage("/login.html") //登录页面设置
.loginProcessingUrl("/user/login") //登录访问路径
.defaultSuccessUrl("/test/index").permitAll() //登录成功之后,跳转路径
.and().authorizeRequests()
.antMatchers("/","/test/hello","/user/login").permitAll() //设置哪些路径可以直接访问,不需要认证
.anyRequest().authenticated()
.and().csrf().disable(); //关闭csrf防护
}
}
1.1 html5
Title
如果当前的主题具有指定的权限,则返回true,否则返回false
1.1在配置类设置当前访问地址有哪些权限
// 当前登录用户,只有具有admins权限才可以访问这个路径 --"/test/index" .antMatchers("/test/index").hasAuthority("admins")
1.2在UserDetailsService,把返回User对象设置权限
Listauths = AuthorityUtils.commaSeparatedStringToAuthorityList("admins");
1.1在配置类设置当前访问地址有哪些权限
//hasAnyAuthority多个权限 .antMatchers("/test/index").hasAnyAuthority("admins,manager")
1.2在UserDetailsService,把返回User对象设置权限
Listauths = AuthorityUtils.commaSeparatedStringToAuthorityList("admins");
1.1在配置类设置当前访问地址有哪些权限
// 3.hasRole方法 .antMatchers("/test/index").hasRole("sale")
1.2在UserDetailsService,把返回User对象设置权限
//这里要注意看看源码格式,有没有加前缀 Listauths = AuthorityUtils.commaSeparatedStringToAuthorityList("admins,sale");