SpringBoot整合Shio

编程入门 行业动态 更新时间:2024-10-27 14:27:29

<a href=https://www.elefans.com/category/jswz/34/1769943.html style=SpringBoot整合Shio"/>

SpringBoot整合Shio

SpringBoot整合Shio

  • 配置shiro
    • 准备实体类:
      • 用户类:
      • 角色类:
      • 权限类:
      • 关系:
      • SQL:
    • 配置ShiroConfig类:
    • 配置Realm类:
      • 身份验证
      • 权限验证

案例源代码取自纯洁的微笑大神的GitHub

配置环境跳过,就介绍核心内容

配置shiro

准备实体类:

用户类:

public class UserInfo implements Serializable {@Id@GeneratedValueprivate Integer uid;@Column(unique =true)private String username;//帐号private String name;//名称(昵称或者真实姓名,不同系统不同定义)private String password; //密码;private String salt;//加密密码的盐private byte state;//用户状态,0:创建未认证(比如没有激活,没有输入验证码等等)--等待验证的用户 , 1:正常状态,2:用户被锁定.@ManyToMany(fetch= FetchType.EAGER)//立即从数据库中进行加载数据;@JoinTable(name = "SysUserRole", joinColumns = { @JoinColumn(name = "uid") }, inverseJoinColumns ={@JoinColumn(name = "roleId") })private List<SysRole> roleList;// 一个用户具有多个角色//省略了get/set
}

角色类:

public class SysRole {@Id@GeneratedValueprivate Integer id; // 编号private String role; // 角色标识程序中判断使用,如"admin",这个是唯一的:private String description; // 角色描述,UI界面显示使用private Boolean available = Boolean.FALSE; // 是否可用,如果不可用将不会添加给用户//角色 -- 权限关系:多对多关系;@ManyToMany(fetch= FetchType.EAGER)@JoinTable(name="SysRolePermission",joinColumns={@JoinColumn(name="roleId")},inverseJoinColumns={@JoinColumn(name="permissionId")})private List<SysPermission> permissions;// 用户 - 角色关系定义;@ManyToMany@JoinTable(name="SysUserRole",joinColumns={@JoinColumn(name="roleId")},inverseJoinColumns={@JoinColumn(name="uid")})private List<UserInfo> userInfos;// 一个角色对应多个用户//省略get/set
}

权限类:

public class SysPermission implements Serializable {@Id@GeneratedValueprivate Integer id;//主键.private String name;//名称.@Column(columnDefinition="enum('menu','button')")private String resourceType;//资源类型,[menu|button]private String url;//资源路径.private String permission; //权限字符串,menu例子:role:*,button例子:role:create,role:update,role:delete,role:viewprivate Long parentId; //父编号private String parentIds; //父编号列表private Boolean available = Boolean.FALSE;@ManyToMany@JoinTable(name="SysRolePermission",joinColumns={@JoinColumn(name="permissionId")},inverseJoinColumns={@JoinColumn(name="roleId")})private List<SysRole> roles;//省略get/set}

关系:

用户与角色是一对多,角色与权限是多对多关系

jpa会根据以上三个实体类生成五个表,分别为:user_info(用户信息表)、sys_role(角色表)、sys_permission(权限表)、sys_user_role(用户角色表)、sys_role_permission(角色权限表),我们插入一下数据:

SQL:

INSERT INTO `sys_permission` (`id`,`available`,`name`,`parent_id`,`parent_ids`,`permission`,`resource_type`,`url`) VALUES (1,0,'用户管理',0,'0/','userInfo:view','menu','userInfo/userList');
INSERT INTO `sys_permission` (`id`,`available`,`name`,`parent_id`,`parent_ids`,`permission`,`resource_type`,`url`) VALUES (2,0,'用户添加',1,'0/1','userInfo:add','button','userInfo/userAdd');
INSERT INTO `sys_permission` (`id`,`available`,`name`,`parent_id`,`parent_ids`,`permission`,`resource_type`,`url`) VALUES (3,0,'用户删除',1,'0/1','userInfo:del','button','userInfo/userDel');
INSERT INTO `sys_role` (`id`,`available`,`description`,`role`) VALUES (1,'0','管理员','admin');
INSERT INTO `sys_role` (`id`,`available`,`description`,`role`) VALUES (2,'0','VIP会员','vip');INSERT INTO `sys_role_permission` VALUES ('1', '1');
INSERT INTO `sys_role_permission` (`permission_id`,`role_id`) VALUES (1,1);
INSERT INTO `sys_role_permission` (`permission_id`,`role_id`) VALUES (1,2);
INSERT INTO `sys_role_permission` (`permission_id`,`role_id`) VALUES (1,3);
INSERT INTO `sys_user_role` (`role_id`,`uid`) VALUES (1,1);
INSERT INTO `user_info` (`uid`,`username`,`name`,`password`,`salt`,`state`) VALUES ('1', 'admin', '管理员', 'd3c59d25033dbf980d29554025c23a75', '8d78869f470951332959580424d4bf4f', 0);

配置ShiroConfig类:

@Beanpublic ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {System.out.println("ShiroConfiguration.shirFilter()");ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();shiroFilterFactoryBean.setSecurityManager(securityManager);//拦截器.Map<String,String> filterChainDefinitionMap = new LinkedHashMap<String,String>();// 配置不会被拦截的链接 顺序判断filterChainDefinitionMap.put("/static/**", "anon");//配置退出 过滤器,其中的具体的退出代码Shiro已经替我们实现了filterChainDefinitionMap.put("/logout", "logout");//<!-- 过滤链定义,从上向下顺序执行,一般将/**放在最为下边 -->:这是一个坑呢,一不小心代码就不好使了;//<!-- authc:所有url都必须认证通过才可以访问; anon:所有url都都可以匿名访问-->filterChainDefinitionMap.put("/**", "authc");// 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面shiroFilterFactoryBean.setLoginUrl("/login");// 登录成功后要跳转的链接shiroFilterFactoryBean.setSuccessUrl("/index");//未授权界面;shiroFilterFactoryBean.setUnauthorizedUrl("/403");shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);return shiroFilterFactoryBean;}

从方法名中可以看出,shiro是通过核心filter来实现权限的安全管理,也就是通过url来进行过滤和权限的校验,在shirFilter方法中正是对url的配置。

Filter Chain定义说明:
1、一个URL可以配置多个Filter,使用逗号分隔
2、当设置多个过滤器时,全部验证通过,才视为通过
3、部分过滤器可指定参数,如perms,roles

其中常用的Filter Chain有:

  • anon 所有配置的URL都可以匿名访问
  • autho 所有配置的URL都需要认证通过才可以访问
  • user 所有配置的URL需要有记住我或认真通过才可以访问
  • logout 配置的URL为登出后跳转的页面,登出的代码shiro已经实现了
  • login 配置的URL为登陆页面,登陆验证的方法在下文会介绍
  • index 登陆成功后跳转的链接
  • 403 无权限访问时跳转的界面

其余配置不详细说明,下载源码后里面有注释

配置Realm类:

身份验证

/*主要是用来进行身份认证的,也就是说验证用户输入的账号和密码是否正确。*/@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token)throws AuthenticationException {System.out.println("MyShiroRealm.doGetAuthenticationInfo()");//获取用户的输入的账号.String username = (String)token.getPrincipal();System.out.println(token.getCredentials());//通过username从数据库中查找 User对象,如果找到,没找到.//实际项目中,这里可以根据实际情况做缓存,如果不做,Shiro自己也是有时间间隔机制,2分钟内不会重复执行该方法UserInfo userInfo = userInfoService.findByUsername(username);System.out.println("----->>userInfo="+userInfo);if(userInfo == null){return null;}SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(userInfo, //用户名userInfo.getPassword(), //密码ByteSource.Util.bytes(userInfo.getCredentialsSalt()),//salt=username+saltgetName()  //realm name);return authenticationInfo;}

在shiro中,登录的账号密码认证是在doGetAuthenticationInfo中实现,这个方法是需要我们重写的。形参AuthenticationToken类中封装了在登录界面输入的账号和密码。
校验步骤为:

  • 根据令牌信息从数据源(通常为数据库)中获取用户信息
  • 对用户信息进行匹配验证。
  • 验证通过将返回一个封装了用户信息的AuthenticationInfo实例。
  • 验证失败则抛出AuthenticationException异常信息。

权限验证

@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {System.out.println("权限配置-->MyShiroRealm.doGetAuthorizationInfo()");SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();UserInfo userInfo  = (UserInfo)principals.getPrimaryPrincipal();for(SysRole role:userInfo.getRoleList()){authorizationInfo.addRole(role.getRole());for(SysPermission p:role.getPermissions()){authorizationInfo.addStringPermission(p.getPermission());}}return authorizationInfo;}

在这个方法中主要是使用类:SimpleAuthorizationInfo进行角色的添加和权限的添加。

更多推荐

SpringBoot整合Shio

本文发布于:2024-03-13 03:16:21,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1733067.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:SpringBoot   Shio

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!