用户实体类

参考:springboot+springsecurity基于角色的权限验证(二)

配置类

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled =true) // 启用授权注解
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {   @Autowiredprivate MyFilterSecurityInterceptor myFilterSecurityInterceptor;/** 获取数据库中信息存到User对象中 */@Beanpublic UserDetailsService userService(){ //注册userService 的beanreturn new UserServiceImpl();}/**加密密码*/@BeanPasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder();}/**MD5加密密码*/@BeanPasswordEncoder md5PasswordEncoder() {return new MD5PasswordEncoder();}/** 放行静态资源 */@Overridepublic void configure(WebSecurity web) throws Exception {//解决静态资源被拦截的问题web.ignoring().antMatchers("/css/**");web.ignoring().antMatchers("/js/**");web.ignoring().antMatchers("/images/**");web.ignoring().antMatchers("/login/**");//解决服务注册url被拦截的问题web.ignoring().antMatchers("/resources/**");}@Overrideprotected void configure(HttpSecurity http) throws Exception {// 登录http.formLogin().loginPage("/toLogin").loginProcessingUrl("/doLogin").defaultSuccessUrl("/index").failureUrl("/toLogin?error=true");  //解决非thymeleaf的form表单提交被拦截问题http.csrf().disable();http.authorizeRequests().antMatchers("/toLogin").permitAll().anyRequest().authenticated()             ;//session管理//session失效后跳转到登录页面  http.sessionManagement().invalidSessionUrl("/toLogin");//单用户登录,如果有一个登录了,同一个用户在其他地方登录将前一个剔除下线//http.sessionManagement().maximumSessions(1).expiredSessionStrategy(expiredSessionStrategy());//单用户登录,如果有一个登录了,同一个用户在其他地方不能登录http.sessionManagement().maximumSessions(1).maxSessionsPreventsLogin(true);//退出删除cookiehttp.logout().permitAll().logoutUrl("/logout")  //执行注销的url.invalidateHttpSession(true) // 指定是否在注销时让httpSession无效.deleteCookies("JESSIONID")  // 清除cookie.logoutSuccessUrl("/toLogin"); // 注销成功后跳转的urlsuper.configure(http);//解决中文乱码问题CharacterEncodingFilter filter = new CharacterEncodingFilter();filter.setEncoding("UTF-8");filter.setForceEncoding(true);//http.addFilterBefore(filter,CsrfFilter.class);http.addFilterBefore(myFilterSecurityInterceptor, FilterSecurityInterceptor.class);}/*** 认证器*/@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {// 自定义加密auth.userDetailsService(userService()).passwordEncoder(md5PasswordEncoder());      }}

创建决策类 MyAccessDecisionManager

/*** 决策管理器(授权)** @ClassName: MyAccessDecisionManager* @description * @author Jayden* @createDate 2019年4月8日-下午2:02:32*/
@Service
public class MyAccessDecisionManager implements AccessDecisionManager {/*** decide 方法是判定是否拥有权限的决策方法,* authentication 是释UserService中循环添加到 GrantedAuthority 对象中的权限信息集合.* object 包含客户端发起的请求的requset信息,可转换为 HttpServletRequest request = ((FilterInvocation) object).getHttpRequest();* * configAttributes 为MyInvocationSecurityMetadataSource的getAttributes(Object object)这个方法返回的结果,* 此方法是为了判定用户请求的url 是否在权限表中,如果在权限表中,则返回给 decide 方法,用来判定用户是否有此权限。如果不在权限表中则放行。* */@Overridepublic void decide(Authentication authentication, Object obj, Collection<ConfigAttribute> configAttributes)throws AccessDeniedException, InsufficientAuthenticationException {if(null== configAttributes || configAttributes.size() <= 0) {return;}ConfigAttribute c;String needRole;for(Iterator<ConfigAttribute> iter = configAttributes.iterator(); iter.hasNext(); ) {c = iter.next();needRole = c.getAttribute();//authentication 为在注释1 中循环添加到 GrantedAuthority 对象中的权限信息集合for(GrantedAuthority ga : authentication.getAuthorities()) {if(needRole.trim().equals(ga.getAuthority())) {return;}}}throw new AccessDeniedException("no right");}@Overridepublic boolean supports(ConfigAttribute configattribute) {// TODO Auto-generated method stubreturn true;}@Overridepublic boolean supports(Class<?> class1) {// TODO Auto-generated method stubreturn true;}}

创建类 MyFilterSecurityInterceptor

@Service
public class MyFilterSecurityInterceptor extends AbstractSecurityInterceptor implements Filter {@Autowiredprivate FilterInvocationSecurityMetadataSource securityMetadataSource;@Autowiredpublic void setMyAccessDecisionManager(MyAccessDecisionManager myAccessDecisionManager) {super.setAccessDecisionManager(myAccessDecisionManager);}@Overridepublic void destroy() {// TODO Auto-generated method stub}@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {FilterInvocation fi = new FilterInvocation(request, response, chain);invoke(fi);}public void invoke(FilterInvocation fi) throws IOException, ServletException {// fi里面有一个被拦截的url// 里面调用MyInvocationSecurityMetadataSource的getAttributes(Object// object)这个方法获取fi对应的所有权限// 再调用MyAccessDecisionManager的decide方法来校验用户的权限是否足够InterceptorStatusToken token = super.beforeInvocation(fi);try {// 执行下一个拦截器fi.getChain().doFilter(fi.getRequest(), fi.getResponse());} finally {super.afterInvocation(token, null);}}@Overridepublic void init(FilterConfig arg0) throws ServletException {// TODO Auto-generated method stub}@Overridepublic Class<?> getSecureObjectClass() {// TODO Auto-generated method stubreturn FilterInvocation.class;}@Overridepublic SecurityMetadataSource obtainSecurityMetadataSource() {// TODO Auto-generated method stubreturn this.securityMetadataSource;} }

创建类 MyInvocationSecurityMetadataSourceService

@Service
public class MyInvocationSecurityMetadataSourceService implements FilterInvocationSecurityMetadataSource {@Autowiredprivate T_permissionMapper permissionMapper;private HashMap<String, Collection<ConfigAttribute>> map =null;/*** 加载权限表中所有权限*/public void loadResourceDefine(){map = new HashMap<>();Collection<ConfigAttribute> array;ConfigAttribute cfg;// 查询到权限表所有信息List<T_permission> permissions = permissionMapper.findAll();for(T_permission permission : permissions) {array = new ArrayList<>();cfg = new SecurityConfig(permission.getName());/***此处只添加了用户的名字,其实还可以添加更多权限的信息,例如请求方法到ConfigAttribute的集合中去。*此处添加的信息将会作为MyAccessDecisionManager类的decide的第三个参数。*/array.add(cfg);//用权限的getUrl() 作为map的key,用ConfigAttribute的集合作为 value,map.put(permission.getUrl(), array);}}@Overridepublic Collection<ConfigAttribute> getAllConfigAttributes() {// TODO Auto-generated method stubreturn null;}/*** 此方法是为了判定用户请求的url 是否在权限表中,如果在权限表中,则返回给 decide 方法,* 用来判定用户是否有此权限。如果不在权限表中则放行。*/@Overridepublic Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException {if(map ==null) loadResourceDefine();//object 中包含用户请求的request 信息HttpServletRequest request = ((FilterInvocation) object).getHttpRequest();AntPathRequestMatcher matcher;String resUrl;for(Iterator<String> iter = map.keySet().iterator(); iter.hasNext(); ) {resUrl = iter.next();matcher = new AntPathRequestMatcher(resUrl);if(matcher.matches(request)) {return map.get(resUrl);}}return null;}@Overridepublic boolean supports(Class<?> class1) {// TODO Auto-generated method stubreturn true;}}

权限 PermissionMapper.xml

用户表,角色表,权限表,用户角色中间表,角色权限中间表

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.jayden.mapper.T_permissionMapper"><!-- 通用查询映射结果 --><resultMap id="BaseResultMap" type="com.jayden.entity.T_permission"><id column="id" property="id" /><result column="name" property="name" /><result column="description" property="description" /><result column="url" property="url" /><result column="pid" property="pid" /></resultMap><!-- 通用查询结果列 --><sql id="Base_Column_List">id, name, description, url, pid</sql><!-- 通过userid查询权限信息 --><select id="selectPermsByUserId" resultMap="BaseResultMap">select p.* from t_user u       LEFT JOIN t_user_role tur on u.id = tur.user_idLEFT JOIN t_role r on tur.role_id = r.idLEFT JOIN t_role_permission trp on trp.role_id = r.idLEFT JOIN t_permission p on p.id = trp.permission_idwhere u.id=#{userId}</select><!-- 查询所有权限 --><select id="findAll" resultMap="BaseResultMap">select * from t_permission</select>

UserDetailsService 实现类

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, T_user> implements UserService, UserDetailsService  {// 用户@Autowiredprivate UserMapper userMapper;// 权限@Autowiredprivate T_permissionMapper permissionMapper;// 加密@Autowiredprivate MD5PasswordEncoder md5PasswordEncoder;        /*** 重写springSecurity类方法*/@Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {// 通过用户名称获取对象T_user user = userMapper.findByUserName(username);if (user != null) {// 因为数据库中密码是明文的,所以在这里加密了(仅测试使用:123为盐)user.setPassword(md5PasswordEncoder.encode(user.getPassword()+"123")); // 通过用户id获取权限信息 List<T_permission> permissions = permissionMapper.selectPermsByUserId(user.getId());List<GrantedAuthority> grantedAuthorities = new ArrayList <>();for (T_permission permission : permissions) {if (permission != null && permission.getName() !=null) {GrantedAuthority grantedAuthority = new SimpleGrantedAuthority(permission.getName());//此处将权限信息添加到 GrantedAuthority 对象中,在后面进行全权限验证时会使用GrantedAuthority 对象grantedAuthorities.add(grantedAuthority);}}return new User(user.getUsername(), user.getPassword(), grantedAuthorities);} else {System.out.println("该用户不存在");throw new UsernameNotFoundException("用户: " + username + " 不存在!");}}}

springboot+springsecurity基于用户表-角色表-权限表的权限控制(三)相关推荐

  1. 用户表 角色表 部门表 级联菜单

    用户表 1 用户表 2 角色表 3 用户角色中间表 4 用户信息详情表 5 部门表 菜单表

  2. 用户表-角色表-权限表多表关联查询sql语句

    在企业系统中经常会使用到给用户分配权限的情况,往往在用户信息表和权限表之间还维护了一张角色表,即通过给用户添加角色,角色添加权限的这样一种方式来给用户间接的添加权限. 如图示例 那么,查询用户权限的多 ...

  3. 表设计----用户表,角色表,权限表

    基于角色的访问控制:(java Web 编程口诀) 用户表角色表,用户角色中间表. 角色表权限表,角色权限中间表. 一个用户可有多个角色,一个角色又可有多个权限.这就是用户-角色-权限授权的模型. 为 ...

  4. rbac权限管理5张表_PHP之常用的RBAC权限管理详解

    文章正文 在说权限管理前,应该先知道权限管理要有哪些功能: (1).用户只能访问,指定的控制器,指定的方法 (2).用户可以存在于多个用户组里 (3).用户组可以选择,指定的控制器,指定的方法 (4) ...

  5. BRAC模型 权限表设计

    在BRAC模型中,涉及到的关键元素有: 用户:系统的使用用户 角色 :拥有相同的权限用户 权限:系统可以被用户操作的元素(如:菜单,超链接) 以上元素的关系: 用户和角色是多对多的关系; 角色和权限是 ...

  6. Shrio之权限表设计

    一.经典5张表 ①用户表 ②角色表 ③用户-角色表 ④菜单表(权限表) ⑤角色菜单表(权限表) 二.权限表设计 1. 菜单表 -- 菜单 CREATE TABLE `sys_menu` (`menu_ ...

  7. 部门人员职位权限表设计

     用户角色多对多  角色权限多对多 用户部门多对多 部门表 用户_部门表 用户表 用户_角色表 角色表     角色_权限表 权限表 用户      用户_角色   (角色)      角色_菜单 ...

  8. 关于权限表的基本设计

    对于一个系统,必须严格的控制权限,权限表的设计是基本的. 基本的权限表有五个,即用户表,角色表,权限表,用户角色表,角色权限表. 下面介绍下基本字段 用户表   user user_id user_n ...

  9. Java权限管理|基于springBoot+springSecurity+jwt实现前后端分离用户权限认证

    基于springBoot+springSecurity+jwt实现前后端分离用户权限认证 1. 项目说明   主要基于前后端分离情况下用户权限认证, 当用户登录认证成功后,每个用户会获取到自己的tok ...

最新文章

  1. 火狐浏览器设置cookie失败_IE、谷歌Cookie记录失败,火狐成功(IE和Firefox下的Cookie兼容问题)...
  2. 使用metasploit中Evasion模块
  3. ONAP — CCVPN 跨域 SDN 协同编排
  4. NeurIPS 2021 助力YOLOv5涨点 Alpha-IoU:IoU Loss大一统
  5. Ubuntu中安装包时提示:you might want to run 'sudo dpkg --configure -a' to correct the problem
  6. mysql某个值连续出现的记录_MySQL-面试必备
  7. C++与Java多态的区别
  8. 不愿意和别人打交道_如果你的交际能力很差,不喜欢与人打交道,这3种职业最适合你...
  9. linux命令之history命令
  10. html5和html的区别是什么?学HTML5要不要学html?
  11. 自制 python 数据分析库
  12. 安装php的mongodb扩展
  13. msyql 1062
  14. 服务器上登录网页ip地址,查看服务器上登录的ip地址
  15. Linux拷贝分区内容,dd复制分区后目标分区的大小变成原分区了
  16. 纯干货:手把手教你用Python做数据可视化(附代码)
  17. 基于海量特征向量数据搜索引擎(达到毫秒级)
  18. 怎么训练 GAN 网络
  19. 【问】SQL 2008安装一直提示重启计算机失败
  20. project项目管理软件の版本区别?

热门文章

  1. ​​​​​​​ABBYY FineReader PDF中文版图片转文字识别工具
  2. opencv人脸识别(python)
  3. 【C++探索之旅】第一部分第十二课:指针一出,谁与争锋
  4. 嵌入式开发38,39,40天(项目3:基于A8开发板的局域网聊天工具)
  5. 鸿蒙系统手机接入点是LTE吗,手机的网络接入点里(APN)有个承载系统,那里面有LTE和eHRPD,是不是表示手机能用4G网?...
  6. 不可不知的结婚照摆放禁忌
  7. css target怎么用
  8. [MTK][FAQ14772] 如何实现插上电池自动开机
  9. android spinner布局,重拾Android之路之Spinner
  10. python输出最小值程序_python程序输出最小值-女性时尚流行美容健康娱乐mv-ida网...