Shiro 的认证操作(Java版)

maven坐标:

        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-all</artifactId>
            <version>1.3.2</version>
        </dependency>
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.2</version>
        </dependency>

建立自定义 Realm,编写认证和授权方法

public class MyRealm extends AuthorizingRealm{
    //授权方法:获取授权信息
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println("执行授权方法...");
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        //资源授权码
        //info.addStringPermission("productAdd");

        //进行通配符授权
        info.addStringPermission("product:*");

        //角色授权码
        info.addRole("admin");
        return info;
    }
    //认证方法:获取认证信息
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        System.out.println("执行认证方法...");
        //判断用户名是否存在, 判断密码是否正确
        //1.如果获取用户输入的账户信息?
        UsernamePasswordToken token = (UsernamePasswordToken)authenticationToken;
        String username = token.getUsername();
        //2.如果获取数据库的账户信息?
        //模拟数据库的账户信息
        String name = "jack";
        String password = "123";
        //判断用户名
        if(!username.equals(name)){
            return null; // shiro 底层自动抛出 UnknownAccountException
        }
        //判断密码
        /**
         * 参数一: principal, 用于把数据回传到 login 方法
         * 参数二: 数据库的密码
         * Shiro 底层对比密码的结果:
         * 1) 密码正确: 认证通过
         * 2) 密码不正确: 自动抛出 IncorrectCredentialsException
         * 参数三: realm 的名称, 只有在多个 realm 的是才会使用
         */
        return new SimpleAuthenticationInfo("callback",password,"");
    }
}

建立 ini 配置 SecurityManager 关联 Realm

myRealm= com.shiro.realms.MyRealm
securityManager.realm=$myRealm

编写 Shiro 的认证流程

public class Test1 {
    public static void main(String[] args) {
        //1.创建安全管理器工厂
        Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
        //2.创建安全管理器
        SecurityManager securityManager = factory.getInstance();
        //3.初始化 SecurityUtils 工具类
        SecurityUtils.setSecurityManager(securityManager);
        //4.从 SecurityUtils 工具中获取 Subject
        Subject subject  = SecurityUtils.getSubject();
        //5.认证操作(登录)
        //AuthenticationToken: 用于封装用户输入的账户信息
        AuthenticationToken token = new UsernamePasswordToken("jack","123");
        try {
            subject.login(token);
            //如果 login 方法没有任何异常, 代表认证成功
            //获取SimpleAuthenticationInfo方法的第一个参数principal
            Object principal = subject.getPrincipal();
            System.out.println("登录成功:"+principal);
        } catch (UnknownAccountException e) {
            //账户不存在
            System.out.println("账户不存在");
        } catch (IncorrectCredentialsException e) {
            //密码错误
            System.out.println("密码错误");
        } catch (Exception e) {
            //系统错误
            System.out.println("系统错误");
        }
    }
}

Shiro 的授权操作分为两种不同方式:
1) 基于资源的授权
必须得到资源的授权码才可以访问该资源
2) 基于角色的授权
必须得到该角色, 才可以访问该资源

注意: 如果要进行 Shiro 的授权操作, 必须先完成 Shiro 的认证。

            subject.login(token);
            //如果 login 方法没有任何异常, 代表认证成功
            //获取SimpleAuthenticationInfo方法的第一个参数principal
            Object principal = subject.getPrincipal();
            System.out.println("登录成功:"+principal);

            //进行 Shiro 的授权

            //1.基于资源的授权
            //判断当前登录用户是否有“商品添加”功能
            //isPermitted():返回 true,有权限, false: 没有权限
            System.out.println("productAdd="+subject.isPermitted("product:add"));
            System.out.println("productUpdate="+subject.isPermitted("product:update"));

            //2.基于角色的授权
            //判断当前登录用户是否为“超级管理员”
            System.out.println("admin="+subject.hasRole("admin"));

猜你喜欢

转载自blog.csdn.net/qq_26641781/article/details/80081409