ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

关于学习Shiro的一些笔记总结(一)

2021-03-08 09:31:41  阅读:169  来源: 互联网

标签:总结 System 笔记 认证 println new subject Shiro out


获取源码和笔记地址:https://gitee.com/monologue_zsj/shiro.git


- Subject:主体
  - 访问系统的用户,主体可以是用户、程序等,进行认证的都称为主体;
- Principal:身份信息
  - 是主体(subject)进行身份认证的标识,标识必须具有唯一性,如用户名、手机号、邮箱地址等,一个主体可以有多个身份,但是必须有一个主身份(Primary Principal)。
- credential:凭证信息
  - 是只有主体自己知道的安全信息,如密码、证书等。

1、shiro-single

 <!--Shrio依赖(maven 项目)-->
<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-core</artifactId>
    <version>1.5.3</version>
</dependency>
#shiro.ini	模拟数据
[users]
xiaozhang=123
zhangsan=123456
lisi=789

1.1 测试认证

/**
 * Created by Monologue_zsj on 2021/3/7 9:58
 * Author:小脸儿红扑扑
 * Description:测试认证
 */
public class TestAuthenticator {
    public static void main(String[] args) {

        //1、创建安全管理器
        DefaultSecurityManager securityManager = new DefaultSecurityManager();
        //2、给安全管理器设置Realm
        securityManager.setRealm(new IniRealm("classpath:shiro.ini"));
        //3、SecurityUtils   给全局安全工具类设置安全管理器
        SecurityUtils.setSecurityManager(securityManager);
        //4、关键对象 subject 主体
        Subject subject = SecurityUtils.getSubject();
        //5、创建令牌
        UsernamePasswordToken token = new UsernamePasswordToken("xiaozhang", "123");
        try {
            System.out.println("认证状态========>" + subject.isAuthenticated());
            subject.login(token);    //用户认证
            System.out.println("认证状态========>" + subject.isAuthenticated());
        } catch (UnknownAccountException e) {
            e.printStackTrace();
            System.out.println("认证失败========> 用户名不存在...");
        }catch (IncorrectCredentialsException e) {
            e.printStackTrace();
            System.out.println("认证失败========> 密码错误...");
        }
    }
}

1.2 自定义Realm

 

/**
 * Created by Monologue_zsj on 2021/3/7 10:43
 * Author:小脸儿红扑扑
 * Description:自定义Realm实现,将认证/授权的数据的来源转为数据库的实现
 */
public class CustomerRealm extends AuthorizingRealm {

    //授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        return null;
    }

    //认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {

        //在token中获取用户名
        String principal = (String) token.getPrincipal();
        //根据身份信息使用jdbc/mybatis...查询相关数据库
        if ("xiaozhang".equals(principal)) {
            /**
             * 参数1:返回数据库中正确的用户名
             * 参数2:返回数据库中正确的密码
             * 参数3:提供当前Realm的名字 this.getName()
             */
            SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(principal, "123", getName());

            return simpleAuthenticationInfo;
        }
        return null;
    }
}
/**
 * Created by Monologue_zsj on 2021/3/7 10:46
 * Author:小脸儿红扑扑
 * Description:使用自定义Realm
 */
public class TestCustomerRealmAuthenticator {
    public static void main(String[] args) {

        //创建SecurityManager
        DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager();
        //设置自定义Realm
        defaultSecurityManager.setRealm(new CustomerRealm());
        //给全局安全工具类设置安全管理器
        SecurityUtils.setSecurityManager(defaultSecurityManager);
        //通过安全工具类获取subject
        Subject subject = SecurityUtils.getSubject();
        //创建token
        UsernamePasswordToken token = new UsernamePasswordToken("xiaozhang", "123");
        try {
            subject.login(token);
        } catch (UnknownAccountException e) {
            e.printStackTrace();
            System.out.println("认证失败========> 用户名不存在...");
        }catch (IncorrectCredentialsException e) {
            e.printStackTrace();
            System.out.println("认证失败========> 密码错误...");
        }

    }
}

1.3 MD5加密

/**
 * Created by Monologue_zsj on 2021/3/7 12:15
 * Author:小脸儿红扑扑
 * Description:MD5加密
 */
public class TestShiroMD5 {
    public static void main(String[] args) {

        //创建一个md5算法
//        Md5Hash md5Hash = new Md5Hash();
//        md5Hash.setBytes("123456".getBytes());
//        String hex = md5Hash.toHex();
//        System.out.println(hex);

        //使用MD5
        Md5Hash md5Hash = new Md5Hash("123456");
        System.out.println(md5Hash.toHex());

        //使用MD5 + salt 处理
        Md5Hash md5Salt = new Md5Hash("123456", "X0*7ps");
        System.out.println(md5Salt);

        //使用MD5 + salt + hash散列(散列次数)
        Md5Hash hash = new Md5Hash("123456", "X0*7ps", 1024);
        System.out.println(hash);
    }
}

/*
	e10adc3949ba59abbe56e057f20f883e	MD5
    e99a0dee78d3c1f71609cead42047675    MD5 + salt
    955224a95d4161ad8bd84f7ede979c02    MD5 + salt + hash
*/

Shiro认证对密码进行加密案例:

/**
 * Created by Monologue_zsj on 2021/3/7 12:23
 * Author:小脸儿红扑扑
 * Description:使用自定义Realm加入 md5 + salt + hash
 */
public class CustomerMD5Realm extends AuthorizingRealm {

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        return null;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {

        //获取身份信息
        String principal = (String) token.getPrincipal();
        //根据用户名查询数据库
        if ("xiaozhang".equals(principal)) {
            /**
             * 参数1:数据库用户名
             * 参数2:数据库md5 + salt之后的密码
             * 参数3:注册时的随机盐
             * 参数4:realm的名字
             */
            return new SimpleAuthenticationInfo(principal,
                    "955224a95d4161ad8bd84f7ede979c02",
                    ByteSource.Util.bytes("X0*7ps"),
                    this.getName());
        }
        return null;
    }
}
/**
 * Created by Monologue_zsj on 2021/3/7 10:46
 * Author:小脸儿红扑扑
 * Description:使用自定义Realm
 */
public class TestCustomerMD5RealmAuthenticator {
    public static void main(String[] args) {

        //创建SecurityManager
        DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager();
        //注入Realm
        CustomerMD5Realm realm = new CustomerMD5Realm();
        //设置Realm使用hash凭证匹配器
        HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();
        //使用的算法
        credentialsMatcher.setHashAlgorithmName("md5");
        //散列的次数
        credentialsMatcher.setHashIterations(1024);
        realm.setCredentialsMatcher(credentialsMatcher);
        //设置自定义Realm
        defaultSecurityManager.setRealm(realm);
        //给全局安全工具类设置安全管理器
        SecurityUtils.setSecurityManager(defaultSecurityManager);
        //通过安全工具类获取subject
        Subject subject = SecurityUtils.getSubject();
        //创建token,认证
        UsernamePasswordToken token = new UsernamePasswordToken("xiaozhang", "123456");
        try {
            subject.login(token);
            System.out.println("登录成功...");
        } catch (UnknownAccountException e) {
            e.printStackTrace();
            System.out.println("认证失败========> 用户名不存在...");
        }catch (IncorrectCredentialsException e) {
            e.printStackTrace();
            System.out.println("认证失败========> 密码错误...");
        }

    }
}

1.4 授权

授权方式

- 基于角色的访问控制

  • RBAC(Role-Based Access Control)是以角色为中心进行访问控制

if(subject.hasRole("admin")) {
    //操作什么资源
}

- 基于资源的访问控制

  • RBAC(Resource-Based Access Control)是以资源为中心进行访问控制

if(subject.isPermission("user:update:01")){	//资源实例
    //对01用户进行修改
}
if(subject.isPermission("user:update:*")){	//资源类型
    //对01用户进行修改
}

权限字符串(资源标识符:操作:资源实例标识符)

  • 用户创建权限:user:create,或user:create:*

  • 用户修改实例001权限:user:update:001

  • 用户实例001的所有权限:user:*:001

/**
 * Created by Monologue_zsj on 2021/3/7 12:23
 * Author:小脸儿红扑扑
 * Description:使用自定义Realm加入 md5 + salt + hash
 */
public class CustomerMD5Realm extends AuthorizingRealm {

    //授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principal) {

        String primaryPrincipal = (String) principal.getPrimaryPrincipal();
        System.out.println("身份信息(用户名)===============》" + primaryPrincipal);
        //根据身份信息获取当前用户的角色信息,以及权限信息
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        //将数据库中查询角色信息赋给权限对象
        simpleAuthorizationInfo.addRole("admin");
        simpleAuthorizationInfo.addRole("user");

        //将数据库中查询权限信息赋值个给权限对象
        simpleAuthorizationInfo.addStringPermission("user:*:01");
        simpleAuthorizationInfo.addStringPermission("product:*:*");

        return simpleAuthorizationInfo;
    }

    //认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        ...
    }
}
/**
 * Created by Monologue_zsj on 2021/3/7 10:46
 * Author:小脸儿红扑扑
 * Description:使用自定义Realm
 */
public class TestCustomerMD5RealmAuthenticator {
    public static void main(String[] args) {

		...
        //认证的用户进行授权
        if (subject.isAuthenticated()) {    //认证成功
            //基于角色的权限控制
            System.out.println("hasRole:" + subject.hasRole("admin"));
            System.out.println("__________________________________________________________________");
            //基于多角色的权限控制
            System.out.println("hasAllRoles:" + subject.hasAllRoles(Arrays.asList("admin", "user")));
            System.out.println("__________________________________________________________________");
            //是否具有其中一个角色
            for (boolean role : subject.hasRoles(Arrays.asList("admin", "user", "super"))) {
                System.out.println("hasRoles:" + role);
            }
            System.out.println("__________________________________________________________________");
            //基于权限字符串的访问控制      资源标识符:操作:资源类型
            System.out.println("isPermitted:" + subject.isPermitted("user:*:01"));
            System.out.println("__________________________________________________________________");
            //分别具有那些权限
            for (boolean permitted : subject.isPermitted("user:*:01", "order:*:10")) {
                System.out.println(permitted);
            }
            System.out.println("__________________________________________________________________");
            //同时具有那些权限 
            System.out.println(subject.isPermittedAll("user:*:01", "product:*"));
        }
    }
}

 

 

 

 

标签:总结,System,笔记,认证,println,new,subject,Shiro,out
来源: https://blog.csdn.net/weixin_42047611/article/details/114519074

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有