spring boot整合 spring security之授权访问
Posted 健康平安的活着
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spring boot整合 spring security之授权访问相关的知识,希望对你有一定的参考价值。
一 授权
二 案例实战
2.1 初始化数据库
1.角色表
CREATE TABLE `t_role` ( `id` varchar(32) NOT NULL, `role_name` varchar(255) DEFAULT NULL, `description` varchar(255) DEFAULT NULL, `create_time` datetime DEFAULT NULL, `update_time` datetime DEFAULT NULL, `status` char(1) NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `unique_role_name` (`role_name`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8
insert into `t_role`(`id`,`role_name`,`description`,`create_time`,`update_time`,`status`) values ('1','管理员',NULL,NULL,NULL,'');
2.角色关联表
CREATE TABLE `t_user_role` ( `user_id` varchar(32) NOT NULL, `role_id` varchar(32) NOT NULL, `create_time` datetime DEFAULT NULL, `creator` varchar(255) DEFAULT NULL, PRIMARY KEY (`user_id`,`role_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8
insert into `t_user_role`(`user_id`,`role_id`,`create_time`,`creator`) values ('1','1',NULL,NULL);
3.权限表
CREATE TABLE `t_permission` ( `id` varchar(32) NOT NULL, `code` varchar(32) NOT NULL COMMENT '权限标识符', `description` varchar(64) DEFAULT NULL COMMENT '描述', `url` varchar(128) DEFAULT NULL COMMENT '请求地址', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8
insert into `t_permission`(`id`,`code`,`description`,`url`) values ('1','p1','测试资源 1','/user/r1'),('2','p3','测试资源2','/user/r2');
4.角色权限表
CREATE TABLE `t_role_permission` ( `role_id` varchar(32) NOT NULL, `permission_id` varchar(32) NOT NULL, PRIMARY KEY (`role_id`,`permission_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8
insert into `t_role_permission`(`role_id`,`permission_id`) values ('1','1'),('1','2');
2.2 查询数据库权限
2.2.1 dao层
<!-- 查询用户信息 -->
<select id="findPermissionsByUserId" resultType="com.ljf.spt.security.model.PermissionDto" >
SELECT id,code,description,url FROM t_permission WHERE id IN (
SELECT permission_id FROM t_role_permission WHERE role_id IN (
SELECT role_id FROM t_user_role WHERE user_id = #{userId}
)
)
</select>
2.2.2 service层
package com.ljf.spt.security.service;
import com.ljf.spt.security.dao.UserMapper;
import com.ljf.spt.security.model.PermissionDto;
import com.ljf.spt.security.model.UserDto;
import org.springframework.beans.factory.annotation.Autowired;
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.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
/**
* @ClassName: SpringDataUserDetailsService
* @Description: TODO
* @Author: liujianfu
* @Date: 2021/08/14 09:44:20
* @Version: V1.0
**/
@Service
public class SpringDataUserDetailsService implements UserDetailsService {
@Autowired
private UserMapper userMapper;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
//将来连接数据库根据账号查询用户信息
UserDto userDto = userMapper.getUserByUsername(username);
if(userDto == null){
//如果用户查不到,返回null,由provider来抛出异常
return null;
}
//权限
// String [] authoritys={"p1"};
//根据用户的id查询用户的权限
List<PermissionDto> permissionsList = userMapper.findPermissionsByUserId(userDto.getId());
List<String> permissions = new ArrayList<>();
permissionsList.forEach(c -> permissions.add(c.getCode()));
//将permissions转成数组
String[] permissionArray = new String[permissions.size()];
permissions.toArray(permissionArray);
UserDetails userDetails = User.withUsername(userDto.getUsername()).password(userDto.getPassword()).authorities(permissionArray).build();
return userDetails;
}
}
2.3 第一种方式web授权
2.3.1 在配置文件中设置
这里需要注意:
.antMatchers("/admin/**").hasRole("ADMIN").antMatchers("/admin/login").permitAll()
因为/ admin / login已经被/ admin / **规则匹配,因此第二个规则被忽略。
应该改为:
.antMatchers("/admin/login").permitAll().antMatchers("/admin/**").hasRole("ADMIN")
2.3.2 测试
1.登录:
2.访问资源1
3.访问资源2:可以看到无权限访问,
bejing用户的角色为管理员,只拥有权限为p1,p1的路径为:/user/r1
2.4 第二种方式方法授权
从Spring Security2.0版 ,它支持服务层方法的安全性的支持。方法注权限校验有: @PreAuthorize,@PostAuthorize, @Secured三类注解。
2.4.1 配置@EnableGlobalMethodSecurity
@EnableGlobalMethodSecurity(securedEnabled = true,prePostEnabled = true)
2.4.2 然后向方法(在类或接口上)添加注解就会限制对该方法的访问
这里在controller的方法设置权限
2.4.3 测试
访问资源1:
访问资源2:
2.5 方法注解的分析
使用如下代码可启用prePost注解的支持:
以上是关于spring boot整合 spring security之授权访问的主要内容,如果未能解决你的问题,请参考以下文章
Spring Boot:Spring Boot整合FreeMarker