1、创建项目
选择相关的依赖:spring Web,springSecurity,mysql,mybatis
创建数据库表
最基本的权限需要的五张表 :用户表(user),角色表(role),权限表(permission),以及他们对应的关系表(user_role,role_permission),表有点多,每张表还有字段 好麻烦呀啊啊啊 不过问题不大! 表我都帮你们建好了 嘿嘿 ,但是表里面只添加了一条数据 我也懒 你们自己加哈哈哈哈
CREATE DATABASE permission
use permission
CREATE TABLE `user`(
id INT PRIMARY KEY AUTO_INCREMENT,
userName VARCHAR(50) NOT NULL,
`password` VARCHAR(50) NOT NULL
)DEFAULT CHARSET'utf8'
CREATE TABLE `role`(
id INT PRIMARY KEY AUTO_INCREMENT,
roleName VARCHAR(50) NOT NULL
)DEFAULT CHARSET'utf8'
CREATE TABLE `permission`(
id INT PRIMARY KEY AUTO_INCREMENT,
permissionName VARCHAR(50) NOT NULL
)DEFAULT CHARSET'utf8'
CREATE TABLE user_role(
id INT PRIMARY KEY AUTO_INCREMENT,
userId INT NOT NULL,
roleId INT NOT NULL
)DEFAULT CHARSET'utf8'
CREATE TABLE role_permission(
id INT PRIMARY KEY AUTO_INCREMENT,
roleId INT NOT NULL,
permissionId INT NOT NULL
)DEFAULT CHARSET'utf8'
INSERT INTO `user`(userName,`password`) VALUES('ahua','123')
INSERT INTO `role`(roleName) VALUES('admin')
INSERT INTO user_role(userId,roleId) VALUES(1,1)
配置我们的application.yml文件
spring:
datasource:
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/permission?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
username: root
password: 123
#mybatis配置
mybatis:
type-aliases-package: com.shenwang.pojo
#mybatis-plus配置
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
mapper-locations: classpath:mappers/*Mapper.xml
然后编写我们最基本的 pojo mapper service
pojo:
User Role Permission
mapper:
UserMapper RoleMapper PermissionMapper 及对应的xml文件
service:
UserService RoleService PermissionService 及对应的实现类
UserService 需要有一个根据userName获取用户的方法
下面代码是实现类(UserServiceImpl)的代码 大家接口(UserService)也不要忘记补上该方法
/**
* <p>
* 服务实现类
* </p>
*
* @author shenwang
* @since 2021-06-22
*/
@Service("userService")
public class UserServiceImpl extends ServiceImpl<UserMapper, UserInfo> implements UserService {
@Resource
private UserMapper userMapper;
@Resource
private RoleMapper roleMapper;
/**
* 根据用户名获取用户
*
* @param userName
* @return
*/
@Override
public UserInfo selectByName(String userName) {
List<UserInfo> users = userMapper.selectList(new QueryWrapper<UserInfo>().eq("userName",userName));
UserInfo userInfo=new UserInfo();
if(users.size()>0)
{
userInfo=users.get(0);
//获取该用户对应的角色并赋予角色
userInfo.setRoleSet(roleMapper.selectByUserId(userInfo.getId()));
}
else
{
userInfo=null;
}
return userInfo;
}
}
要从数据库读取用户信息进行身份验证需要创建一个类实现UserDetailsService接口重写loadUserByUsername方法:
package com.shenwang.security;
import com.shenwang.pojo.Role;
import com.shenwang.pojo.UserInfo;
import com.shenwang.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
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 java.util.ArrayList;
import java.util.List;
import java.util.Set;
/**
* @author: shenwang
* Date: 2021/6/23
*/
@Component
public class CustomUserDetailsService implements UserDetailsService {
@Autowired
private UserService userService;
/**
* 配置新建类注册一个指定的加密方式Bean,或者在下一步Security配置类中注册指定
*/
@Autowired
private PasswordEncoder passwordEncoder;
@Override
public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
//通过用户名获取用户信息
UserInfo userInfo = userService.selectByName(s);
if(userInfo==null)
{
throw new UsernameNotFoundException("用户不存在");
}
//角色集合
List<GrantedAuthority> authorities = new ArrayList<>();
//得到用户角色
Set<Role> roleSet = userInfo.getRoleSet();
for (Role role:roleSet)
{
authorities.add(new SimpleGrantedAuthority("ROLE_"+role.getRoleName()));
}
return new User(userInfo.getUserName(),userInfo.getPassword(),authorities);
}
}
创建spring security的配置类WebSecurityConfig继承WebSecurityConfigurerAdapter,并重写configure(auth)方法:
/**
* @author: shenwang
* Date: 2021/6/23
*/
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private CustomUserDetailsService userDetailsService;
/**
* 指定加密方式
* @return
*/
@Bean
public PasswordEncoder passwordEncoder(){
//使用BCrypt加密密码
return new BCryptPasswordEncoder();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//从数据库获取用户信息进行身份验证
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
}
最后是我的Controller层代码
package com.shenwang.controller;
import com.shenwang.pojo.UserInfo;
import com.shenwang.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
/**
* @author: shenwang
* Date: 2021/6/23
*/
@RestController
public class TestController {
@Autowired
private UserService userService;
/**
* 根据用户名获取用户
* @param userName
* @return
*/
@GetMapping("getUser/{userName}")
public UserInfo getUser(@PathVariable String userName){
return userService.selectByName(userName);
}
/**
* hello world!
* @return
*/
@PreAuthorize(value ="hasRole(ROLE_ADMIN)")
@GetMapping("hello")
public String hello(){
return "hello spring security! hello world!";
}
}
现在我们就可启动我们的项目啦 没有登录是不能访问里面的方法的哟~ 没有登录访问的话还是会跳回咱们的登录界面
因为我们请求过的密码是经过springSecurity加密的 前端:123 到咱们的 后端 就是$2a$10$9vykje4fYOGEw.LfS4saXuHUm.WEkE95PSFbYWwQ0J0OAmBjUfjnC所以咱们存在数据库中的密码也是需要加密的 怎么从123 到加密后的密码呢 只需要在测试类中执行一下代码就好:
@SpringBootTest
class PasswordTest {
@Test
void contextLoads() {
BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
String encode = bCryptPasswordEncoder.encode("123");
System.out.println(encode);
}
}
最后咱们就可以测试咱们的权限啦!