基于Springboot + Spring Security Oauth2.0 + Jwt实现RBAC权限模型,这几个概念就不做描述了,例子很多
整合Spring Security
pom.xml依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
引入依赖后啥也没做,启动项目发现就需要先经过登录界面了,再自己没有提供登录页面的时候,默认是spring security提供的登录界面
编写Spring Security配置类和UserDetailsServiceImpl
根据自己的需求实现父类的一些方法,用户信息先放在内存的,方便测试权限之类的,后面通过数据库存储。Spring Security中进行身份验证的是AuthenticationManager接口,ProviderManager是它的一个默认实现,但它并不用来处理身份认证,而是委托给配置好的AuthenticationProvider,每个AuthenticationProvider会轮流检查身份认证。验证身份就是加载响应的UserDetails,看看是否和用户输入的账号、密码、权限等信息匹配。此步骤由实现AuthenticationProvider的DaoAuthenticationProvider(它利用UserDetailsService验证用户名、密码和授权)处理。
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true, jsr250Enabled = true)
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
/**
* 密码编码器
* @return
*/
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public UserDetailsService userDetailsService() {
return new UserDetailsServiceImpl();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService());
//基于内存存储用户信息
/* auth.inMemoryAuthentication()
.withUser("admin").password(passwordEncoder().encode("123")).authorities("p1") //登录用户admin密码123拥有“p1”权限
.and()
.withUser("zfy").password(passwordEncoder().encode("456")).authorities("p2");*/
}
/**
* 安全拦截机制
*
* @param http
* @throws Exception
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/api/**").authenticated()
.and()
.formLogin().permitAll()
.and()
.csrf().disable();
/* http.authorizeRequests()
.antMatchers("/api/p/p1").hasAnyAuthority("p1")//权限控制
.antMatchers("/api/p/p2").hasAnyAuthority("p2")
.antMatchers("/api/p/**").authenticated()//所有/api/p开头的请求都必须经过认证
.anyRequest().permitAll()//其余的可以直接访问
.and()
.formLogin().permitAll();*/
}
}
这里的HttpSecurity的一些api可以参考Spring Security中HttpSecurity常用方法及说明
public class UserDetailsServiceImpl implements UserDetailsService {
@Autowired
private UserService userService;
@Autowired
private PermissionService permissionService;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userService.getByUsername(username);
if (user == null)
return null;
List<Permission> permissionList = permissionService.queryByUserId(user.getId());
List<GrantedAuthority> grantedAuthorities = new ArrayList<>();
if (permissionList != null && !permissionList.isEmpty())
permissionList.forEach(permission -> {
if (permission != null && !StringUtils.isEmpty(permission.getEnname())) {
SimpleGrantedAuthority authority = new SimpleGrantedAuthority(permission.getEnname());
grantedAuthorities.add(authority);
}
});
return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(), grantedAuthorities);
}
}
测试资源
通过数据库配置的资源去掉了这个权限标识,所以访问的时候返回的状态码为403(此时为未授权),访问其他的接口没问题
此时整个项目结构
整合的Oauth2.0在下篇文章里Springboot整合Spring Security Oauth2.0 + JWT (二)
以上的sql脚本
DROP TABLE IF EXISTS `tb_permission`;
CREATE TABLE `tb_permission` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`parent_id` bigint(20) DEFAULT NULL COMMENT '父权限',
`name` varchar(64) NOT NULL COMMENT '权限名称',
`enname` varchar(64) NOT NULL COMMENT '权限英文名称',
`url` varchar(255) NOT NULL COMMENT '授权路径',
`description` varchar(200) DEFAULT NULL COMMENT '备注',
`created` datetime NOT NULL,
`updated` datetime NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=49 DEFAULT CHARSET=utf8 COMMENT='权限表';
-- ----------------------------
-- Records of tb_permission
-- ----------------------------
INSERT INTO `tb_permission` VALUES ('37', '0', '系统管理', 'System', '/', null, '2019-04-04 23:22:54', '2019-04-04 23:22:56');
INSERT INTO `tb_permission` VALUES ('38', '37', '用户管理', 'SystemUser', '/users/', null, '2019-04-04 23:25:31', '2019-04-04 23:25:33');
INSERT INTO `tb_permission` VALUES ('39', '38', '查看用户', 'SystemUserView', '/users/view/**', null, '2019-04-04 15:30:30', '2019-04-04 15:30:43');
INSERT INTO `tb_permission` VALUES ('40', '38', '新增用户', 'SystemUserInsert', '/users/insert/**', null, '2019-04-04 15:30:31', '2019-04-04 15:30:44');
INSERT INTO `tb_permission` VALUES ('41', '38', '编辑用户', 'SystemUserUpdate', '/users/update/**', null, '2019-04-04 15:30:32', '2019-04-04 15:30:45');
INSERT INTO `tb_permission` VALUES ('42', '38', '删除用户', 'SystemUserDelete', '/users/delete/**', null, '2019-04-04 15:30:48', '2019-04-04 15:30:45');
INSERT INTO `tb_permission` VALUES ('44', '37', '内容管理', 'SystemContent', '/contents/', null, '2019-04-06 18:23:58', '2019-04-06 18:24:00');
INSERT INTO `tb_permission` VALUES ('45', '44', '查看内容', 'SystemContentView', '/contents/view/**', null, '2019-04-06 23:49:39', '2019-04-06 23:49:41');
INSERT INTO `tb_permission` VALUES ('46', '44', '新增内容', 'SystemContentInsert', '/contents/insert/**', null, '2019-04-06 23:51:00', '2019-04-06 23:51:02');
INSERT INTO `tb_permission` VALUES ('47', '44', '编辑内容', 'SystemContentUpdate', '/contents/update/**', null, '2019-04-06 23:51:04', '2019-04-06 23:51:06');
INSERT INTO `tb_permission` VALUES ('48', '44', '删除内容', 'SystemContentDelete', '/contents/delete/**', null, '2019-04-06 23:51:08', '2019-04-06 23:51:10');
-- ----------------------------
-- Table structure for tb_role
-- ----------------------------
DROP TABLE IF EXISTS `tb_role`;
CREATE TABLE `tb_role` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`parent_id` bigint(20) DEFAULT NULL COMMENT '父角色',
`name` varchar(64) NOT NULL COMMENT '角色名称',
`enname` varchar(64) NOT NULL COMMENT '角色英文名称',
`description` varchar(200) DEFAULT NULL COMMENT '备注',
`created` datetime NOT NULL,
`updated` datetime NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=38 DEFAULT CHARSET=utf8 COMMENT='角色表';
-- ----------------------------
-- Records of tb_role
-- ----------------------------
INSERT INTO `tb_role` VALUES ('37', '0', '超级管理员', 'admin', null, '2019-04-04 23:22:03', '2019-04-04 23:22:05');
-- ----------------------------
-- Table structure for tb_role_permission
-- ----------------------------
DROP TABLE IF EXISTS `tb_role_permission`;
CREATE TABLE `tb_role_permission` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`role_id` bigint(20) NOT NULL COMMENT '角色 ID',
`permission_id` bigint(20) NOT NULL COMMENT '权限 ID',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=48 DEFAULT CHARSET=utf8 COMMENT='角色权限表';
-- ----------------------------
-- Records of tb_role_permission
-- ----------------------------
INSERT INTO `tb_role_permission` VALUES ('37', '37', '37');
INSERT INTO `tb_role_permission` VALUES ('38', '37', '38');
INSERT INTO `tb_role_permission` VALUES ('40', '37', '40');
INSERT INTO `tb_role_permission` VALUES ('41', '37', '41');
INSERT INTO `tb_role_permission` VALUES ('42', '37', '42');
INSERT INTO `tb_role_permission` VALUES ('44', '37', '45');
INSERT INTO `tb_role_permission` VALUES ('45', '37', '46');
INSERT INTO `tb_role_permission` VALUES ('46', '37', '47');
INSERT INTO `tb_role_permission` VALUES ('47', '37', '48');
-- ----------------------------
-- Table structure for tb_user
-- ----------------------------
DROP TABLE IF EXISTS `tb_user`;
CREATE TABLE `tb_user` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`username` varchar(50) NOT NULL COMMENT '用户名',
`name` varchar(255) NOT NULL,
`password` varchar(64) NOT NULL COMMENT '密码,加密存储',
`phone` varchar(20) DEFAULT NULL COMMENT '注册手机号',
`email` varchar(50) DEFAULT NULL COMMENT '注册邮箱',
`created` datetime NOT NULL,
`updated` datetime NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `username` (`username`) USING BTREE,
UNIQUE KEY `phone` (`phone`) USING BTREE,
UNIQUE KEY `email` (`email`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=38 DEFAULT CHARSET=utf8 COMMENT='用户表';
-- ----------------------------
-- Records of tb_user
-- ----------------------------
INSERT INTO `tb_user` VALUES ('37', 'admin', '阿德曼', '$2a$10$hty8OGt7DQ/ihHMIKFdYrOxaxqrRVHUBIx90Aw2KDYsw6KBB2gKXu', '15888888888', 'lee.lusifer@gmail.com', '2019-04-04 23:21:27', '2019-04-04 23:21:29');
-- ----------------------------
-- Table structure for tb_user_role
-- ----------------------------
DROP TABLE IF EXISTS `tb_user_role`;
CREATE TABLE `tb_user_role` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`user_id` bigint(20) NOT NULL COMMENT '用户 ID',
`role_id` bigint(20) NOT NULL COMMENT '角色 ID',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=38 DEFAULT CHARSET=utf8 COMMENT='用户角色表';
-- ----------------------------
-- Records of tb_user_role
-- ----------------------------
INSERT INTO `tb_user_role` VALUES ('37', '37', '37');