请选择 进入手机版 | 继续访问电脑版

Shiro权限管理系统设计与实现

[复制链接]
发表于 2018-12-21 13:46:02 |显示全部楼层
主要实现功能:
         根据用户名和密码登录判断是否存在于系统中,并查询出该用户的角色权限等信息。

实现技术:

bootstrap+shiro+springboot+mysql

数据库设计:
http://xuejava.org/forum.php?mod ... age=1&extra=#pid581

创建Shiro应用:       这一步,我打算啰嗦一点。

     1.1 打开Idea开发工具,创建一个Maven项目。(使用Idea创建SpringBoot Maven项目:如何创建一个Maven项目)

     1.2 创建一个system模块。该模块所保存内容为Shiro的登录信息等。

     1.3 配置Pom.xml文件。


     1.5 后台登陆Controller;
     
  1.     @PostMapping("/login")
  2.     @ResponseBody
  3.     public AjaxResult ajaxLogin(String username, String password, Boolean rememberMe)
  4.     {
  5.         UsernamePasswordToken token = new UsernamePasswordToken(username, password, rememberMe);
  6.         Subject subject = SecurityUtils.getSubject();
  7.         try
  8.         {
  9.             subject.login(token);
  10.             return success();
  11.         }
  12.         catch (AuthenticationException e)
  13.         {
  14.             String msg = "用户或密码错误";
  15.             if (StringUtils.isNotEmpty(e.getMessage()))
  16.             {
  17.                 msg = e.getMessage();
  18.             }
  19.             return error(msg);
  20.         }
  21.     }
复制代码


数据库设计:
























   Apache Shiro是Java的一个安全框架。Shiro可以帮助我们完成:认证、授权、加密、会话管理、与Web集成、缓存等。其不仅可以用在 JavaSE环境,也可以用在 JavaEE 环境

    Shiro 原生的 Token 中存在用户名和密码以及其他信息 [验证码,记住我]
   
    作为一款安全框架Shiro的设计相当精妙。Shiro的应用不依赖任何容器,也就是说使用Shiro可以在非WEB项目中使用。不过一

般情况下我们肯定绝大部分接触的都是web项目,那么我就说一下用户登录实例。

   

     根据Shiro的设计思路,用户与角色之前的关系为多对多,角色与权限之间的关系也是多对多。在数据库中需要因此建立5张

表,分别是用户表(存储用户名,密码,盐等)、角色表(角色名称,相关描述等)、权限表(权限名称,相关描述等)、用

户-角色对应中间表(以用户ID和角色ID作为联合主键)、角色-权限对应中间表(以角色ID和权限ID作为联合主键)。具体

dao与service的实现本文不提供。总之结论就是,Shiro需要根据用户名和密码首先判断登录的用户是否合法,然后再对合法

用户授权。而这个过程就是Realm的实现过程。

三个核心组件:Subject, SecurityManager 和 Realms.
Subject:即“当前操作用户”。但是,在Shiro中,Subject这一概念并不仅仅指人,也可以是第三方进程、后台帐户(Daemon Account)或其他类似事物。它仅仅意味着“当前跟软件交互的东西”。
  Subject代表了当前用户的安全操作,SecurityManager则管理所有用户的安全操作。
  SecurityManager:它是Shiro框架的核心,典型的Facade模式,Shiro通过SecurityManager来管理内部组件实例,并通过它来提供安全管理的各种服务。
  Realm: Realm充当了Shiro与应用安全数据间的“桥梁”或者“连接器”。也就是说,当对用户执行认证(登录)和授权(访问控制)验证时,Shiro会从应用配置的Realm中查找用户及其权限信息。
  从这个意义上讲,Realm实质上是一个安全相关的DAO:它封装了数据源的连接细节,并在需要时将相关数据提供给Shiro。当配置Shiro时,你必须至少指定一个Realm,用于认证和(或)授权。配置多个Realm是可以的,但是至少需要一个。
  Shiro内置了可以连接大量安全数据源(又名目录)的Realm,如LDAP、关系数据库(JDBC)、类似INI的文本配置资源以及属性文件等。如果缺省的Realm不能满足需求,你还可以插入代表自定义数据源的自己的Realm实现

    前端代码:
   
       <input type="text">
       <input type="text" id="password" name="password">
     
    后端测试用例:
   
  1.     @PostMapping("/login")
  2.     @ResponseBody
  3.     public AjaxResult ajaxLogin(String username, String password, Boolean rememberMe)
  4.     {
  5.         UsernamePasswordToken token = new UsernamePasswordToken(username, password, rememberMe);
  6.         Subject subject = SecurityUtils.getSubject();   
  7.         try
  8.         {
  9.             subject.login(token);
  10.             return success();
  11.         }
  12.         catch (AuthenticationException e)
  13.         {
  14.             String msg = "用户或密码错误";
  15.             if (StringUtils.isNotEmpty(e.getMessage()))
  16.             {
  17.                 msg = e.getMessage();
  18.             }
  19.             return error(msg);
  20.         }
  21.     }
复制代码



数据库设计



Shiro的配置






Shiro获取用户权限


  第一步:我们使用用户的登陆信息作为token令牌。
  UsernamePasswordToken token = new UsernamePasswordToken(username, password);


获取用户的角色和权限信息


  
  1. public class UserRealm extends AuthorizingRealm {
  2.     // 用户对应的角色信息与权限信息都保存在数据库中,通过UserService获取数据
  3.     private UserService userService = new UserServiceImpl();

  4.     /**
  5.      * 提供用户信息返回权限信息
  6.      */
  7.     @Override
  8.     protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
  9.         String username = (String) principals.getPrimaryPrincipal();
  10.         SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
  11.         // 根据用户名查询当前用户拥有的角色
  12.         Set<Role> roles = userService.findRoles(username);
  13.         Set<String> roleNames = new HashSet<String>();
  14.         for (Role role : roles) {
  15.             roleNames.add(role.getRole());
  16.         }
  17.         // 将角色名称提供给info
  18.         authorizationInfo.setRoles(roleNames);
  19.         // 根据用户名查询当前用户权限
  20.         Set<Permission> permissions = userService.findPermissions(username);
  21.         Set<String> permissionNames = new HashSet<String>();
  22.         for (Permission permission : permissions) {
  23.             permissionNames.add(permission.getPermission());
  24.         }
  25.         // 将权限名称提供给info
  26.         authorizationInfo.setStringPermissions(permissionNames);

  27.         return authorizationInfo;
  28.     }

  29.     /**
  30.      * 提供账户信息返回认证信息
  31.      */
  32.     @Override
  33.     protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
  34.         String username = (String) token.getPrincipal();
  35.         User user = userService.findByUsername(username);
  36.         if (user == null) {
  37.             // 用户名不存在抛出异常
  38.             throw new UnknownAccountException();
  39.         }
  40.         if (user.getLocked() == 0) {
  41.             // 用户被管理员锁定抛出异常
  42.             throw new LockedAccountException();
  43.         }
  44.         SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(user.getUsername(),
  45.                 user.getPassword(), ByteSource.Util.bytes(user.getCredentialsSalt()), getName());
  46.         return authenticationInfo;
  47.     }
  48. }
复制代码






原文地址:http://xuejava.org/thread-337-1-1.html
Shiro.sojson.com/shiro
https://www.cnblogs.com/learnhow/p/5694876.html
您需要登录后才可以回帖 登录 | 立即注册

Archiver|手机版|沙漏笔记

GMT+8, 2020-12-3 10:11 , Processed in 1.248943 second(s), 21 queries .

Powered by Discuz! X2.5

© 2001-2012 Comsenz Inc.

Copyright © 2015-2018 xuejava网 / 鲁ICP备17054568号-1
回顶部