当前位置:主页 > 查看内容

shiro权限安全框架

发布时间:2021-05-09 00:00| 位朋友查看

简介:shiro权限安全框架 什么是shiro 认证和授权 为什么要学shiro---安全 快速入门shiro 授权 什么是shiro 认证和授权 Apache Shiro 是Java 的一个安全框架。Shiro 可以非常容易的开发出足够好的应用其不仅可以用在JavaSE 环境也可以用在JavaEE 环境。Shiro 可以……

什么是shiro 认证和授权

Apache Shiro 是Java 的一个安全框架。Shiro 可以非常容易的开发出足够好的应用,其不仅可以用在JavaSE 环境,也可以用在JavaEE 环境。Shiro 可以帮助我们完成:认证【登陆】、授权【权限】、加密【密码】、会话管理、与Web 集成、缓存等。

为什么要学shiro—安全

在这里插入图片描述
subject: 理解为用户;

securityManager: 安全管理 它是核心组件。

Authenticator: 认证器

Authorizer: 授权器。

Realm: 理解为和数据库交互的一个组件。使用InitRealm—读取ini文件的内容。

快速入门shiro

(1)引入shiro-core的依赖

     <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-core</artifactId>
            <version>1.7.0</version>
        </dependency>

(2)创建一个ini文件 好比数据库 必须叫 users表示用户表

 #表示用户表 存放着账户和密码
[users]
zs=111
ls=222

(3)测试
退出登录 :subject.logout();
判断当前用户是否认证成功:subject.isAuthenticated()

   public static void main(String[] args) {
//        1.得到securityManager对象
        DefaultSecurityManager securityManager = new DefaultSecurityManager();
//        2.设置securityManager管理的realm对象
        securityManager.setRealm(new IniRealm("classpath:shiro.ini"));
//        3.把securityManager绑定到securityManager
        SecurityUtils.setSecurityManager(securityManager);
//        4.获取Subject对象
        Subject subject = SecurityUtils.getSubject();
//       封装账户和密码
        UsernamePasswordToken token = new UsernamePasswordToken("zs", "111");
        try {
//      5.执行认证功能
            subject.login(token);
            System.out.println("账户和密码正确");
        } catch (Exception e){
            e.printStackTrace();
            System.out.println("账户和密码错误");
        }
//       isAuthenticated判断当前的用户是否被认证
        System.out.println("是否认证成功"+subject.isAuthenticated());
//        退出登录
        subject.logout();
//        isAuthenticated判断当前用户是否认证成功
        System.out.println("是否认证成功"+subject.isAuthenticated());
    }

认证的流程:
在这里插入图片描述
流程如下:

首先调用 Subject.login(token) 进行登录,其会自动委托给 Security 			  Manager,调用之前必须通过 SecurityUtils.setSecurityManager() 设置;
SecurityManager 负责真正的身份验证逻辑;它会委托给 Authenticator 	进行身份验证;
Authenticator 才是真正的身份验证者,Shiro API 中核心的身份认证入口点,此处可以自定义插入自己的实现;
Authenticator 可能会委托给相应的 AuthenticationStrategy 进行多 Realm 身份验证,默认 ModularRealmAuthenticator 会调用 AuthenticationStrategy 进行多 Realm 身份验证;
Authenticator 会把相应的 token 传入 Realm,从 Realm 获取身份验证信息,如果没有返回 / 抛出异常表示身份验证失败了。此处可以配置多个 Realm,将按照相应的顺序及策略进行访问。

授权

(1)在ini文件中

 #表示用户表 存放着账户和密码
[users]
zs=111,admin
ls=222,role1

#表示角色表 包含角色的名称 角色具有的权限
[roles]
admin=user:query,user:delete,user:update,user:insert
role1=user:query
role2=user:query,user:update
role3=user:export

(2)测试授权,注意认证之后,再进行授权
当前认证后的用户是否具有user:query:subject.isPermitted(“user:query”)
当前认证后的用户是否具有多个权限:subject.isPermittedAll(“user:query”,“user:export”)
部分测试代码:


//          授权
        System.out.println("当前认证后的用户是否具有user:query:"+subject.isPermitted("user:query"));
        System.out.println("当前认证后的用户是否具有多个权限:"+subject.isPermittedAll("user:query","user:export"));
    }

完整测试代码:

//        1.得到securityManager对象
        DefaultSecurityManager securityManager = new DefaultSecurityManager();
//        2.设置securityManager管理的realm对象
        securityManager.setRealm(new IniRealm("classpath:shiro.ini"));
//        3.把securityManager绑定到securityManager
        SecurityUtils.setSecurityManager(securityManager);
//        4.获取Subject对象
        Subject subject = SecurityUtils.getSubject();
//       封装账户和密码
        UsernamePasswordToken token = new UsernamePasswordToken("zs", "111");
        try {
//      5.执行认证功能
            subject.login(token);
            System.out.println("账户和密码正确");
        } catch (Exception e){
            e.printStackTrace();
            System.out.println("账户和密码错误");
        }

//       isAuthenticated判断当前的用户是否被认证
        System.out.println("是否认证成功"+subject.isAuthenticated());
/*//        退出登录
        subject.logout();
//        isAuthenticated判断当前用户是否认证成功
        System.out.println("是否认证成功"+subject.isAuthenticated());*/

//          授权
        System.out.println("当前认证后的用户是否具有user:query:"+subject.isPermitted("user:query"));
        System.out.println("当前认证后的用户是否具有多个权限:"+subject.isPermittedAll("user:query","user:export"));
  

**注意:**上面这些代码都是ini数据,实际开发肯定通过数据库进行的判断。
根据iniRealm创建自己的realm类,该类中就可以写自己连接数据库的内容。
创建MyRealm继承AuthorizingRealm,并重写doGetAuthorizationInfo和doGetAuthenticationInfo的方法
自己创建MyRealm类
绑定权限 SimpleAuthorizationInfo
SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();
info.addStringPermissions(permission);
SimpleAuthenticationInfo类中的三个参数代表的意思:
Object principal,账号 可以被登录成功后获取,还可以传给授权的方法
Object credentials,从数据库中查询的密码
String realmName 当前realm的名称
认证
SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user,user.getPassWord(),this.getName());

this.getName()表示调用父类的方法

package com.myrealm;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;

import java.util.List;

/**
 * @author : 小峥
 * @date : 2021/4/5 0:46
 * @description:
 */
public class MyRealm extends AuthorizingRealm {
  /*  @AutoWird
    private UserService userService;*/

    private UserService userService = new UserService();

    //    当执行授权时调用该方法
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        User user = (User) principalCollection.getPrimaryPrincipal();
        System.out.println("授权方法的执行"+user);
//        根据用户id擦混该用户具有的权限码
      List<String> permission=userService.findPermissionById(user.getId());
//      绑定权限
        SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();
        info.addStringPermissions(permission);
        return info;
    }

    //当执行认证功能时调用该方法  认证时捕获异常
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        System.out.println("认证方法的执行");
//        得到账户  唯一的标识
        String loginName = authenticationToken.getPrincipal().toString();
//        System.out.println("你登录的账户值为:" + loginName);
//        调用service中的方法 根据用户名查询用户信息
        User user = userService.findByLoginName(loginName);
        if (user!=null){
//            Object principal,账号  可以被登录成功后获取,还可以传给授权的方法
//            Object credentials,从数据库中查询的密码
//            String realmName 当前realm的名称
//            SimpleAuthenticationInfo info = new SimpleAuthenticationInfo("hhhhhhh",user.getPassWord(),this.getName());
            SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user,user.getPassWord(),this.getName());
            return info;
        }
        return null;
    }
}

service层

public class UserService {
    public User findByLoginName(String loginName) {
        switch (loginName) {
            case "admin":
                return new User(1, "admin", "111", "管理员");
            case "zs":
                return new User(2, "zzz", "222", "张三");
            case "ls":
                return new User(3, "lll", "333", "李四");
            default:
                return null;
        }
    }

    public List<String> findPermissionById(int id) {
        List<String> list=new ArrayList<>();
        if (id==1){
            list.add("user:query");
            list.add("user:delete");
            list.add("user:update");
            list.add("user:insert");
        }else if (id==2){
            list.add("user:query");
        }else if (id==3){
            list.add("user:delete");
            list.add("user:update");
        }
        return list;
    }
}

测试类

public class Demo {
    public static void main(String[] args) {
//        得到SecurityManager对象
        DefaultSecurityManager securityManager = new DefaultSecurityManager();
//        设置securityManager管理的realm对象
        MyRealm myRealm = new MyRealm();
        securityManager.setRealm(myRealm);
//        把securityManager绑定到SecurityUtilss
        SecurityUtils.setSecurityManager(securityManager);
//        获取subject对象
        Subject subject = SecurityUtils.getSubject();
//        封装账户和密码
        UsernamePasswordToken token=new UsernamePasswordToken("zs","222");
        subject.login(token);
        Object principal = subject.getPrincipal();
        System.out.println(principal);
//        认证-->登录
        System.out.println("认证成功:"+subject.isAuthenticated());


//        只有认证之后才能执行MyRealm中的认证方法
        System.out.println("查询权限:"+subject.isPermittedAll("user:query"));

    }
}
;原文链接:https://blog.csdn.net/weixin_45861581/article/details/115429803
本站部分内容转载于网络,版权归原作者所有,转载之目的在于传播更多优秀技术内容,如有侵权请联系QQ/微信:153890879删除,谢谢!
上一篇:BUUCTF 每日打卡 2021-4-5 下一篇:没有了

推荐图文


随机推荐