zoukankan      html  css  js  c++  java
  • (3)shiro自定义realm

    上面一章说到shiro的认证和授权最底层就是调用realm的getAuthorizationInfo(获取用户的角色和资源)和getAuthenticationInfo(校验账号密码是否正确)两个方法。

    如果我们要从数据库中查询用户和他的权限信息,我们可以使用shiro提供给我们的JdbcRealm

     JdbcRealm

     添加jar

    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.25</version>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>0.2.23</version>
    </dependency>

    classpath环境下新建shiro-jdbc.ini如下配置
    这里我们采用了阿里巴巴的数据源,注入到jdbcRealm的dataSource变量中,并且将这个jdbcRealm注入到securityManager,有点类似于spring的注入。

    下面的sql放在github上对应的章节根目录下,导入即可,数据库密码填写自己数据库密码

    jdbcRealm=org.apache.shiro.realm.jdbc.JdbcRealm
    dataSource=com.alibaba.druid.pool.DruidDataSource
    dataSource.driverClassName=com.mysql.jdbc.Driver
    dataSource.url=jdbc:mysql://localhost:3306/shiro
    dataSource.username=root
    dataSource.password=123456
    jdbcRealm.dataSource=$dataSource
    #注入securityManager的realm
    securityManager.realms=$jdbcRealm

    测试代码:

    ShiroUtils.login("classpath:shiro-jdbc.ini","zhang","123456");
    Subject subject = SecurityUtils.getSubject();
    //是否通过认证
    System.out.println(subject.isAuthenticated());

    其中ShiroUtils的登录方法(这个以后直接略过):

        public static void login(String configPath,String username,String password){
            Factory<SecurityManager> factory =new IniSecurityManagerFactory(configPath);
            //得到安全管理器
            SecurityManager securityManager = factory.getInstance();
    
            SecurityUtils.setSecurityManager(securityManager);
    
            Subject subject = SecurityUtils.getSubject();
    
            UsernamePasswordToken token = new UsernamePasswordToken(username, password);
    
    
            try {
                subject.login(token);
            } catch (AuthenticationException e) {
                e.printStackTrace();
            }
        }
    View Code

    最后输出true。

    因为jdbcRealm里面的sql都是固定的,所以我们表结构都要按照JdbcRealm里面创建对应的表。下面是JdbcRealm里面各种查询的sql(salt是密码加密,后面介绍加密再说,我们这里直接用明文密码)

    表里面数据分别如下

    接着测试代码添加如下:

            System.out.println(subject.hasRole("role1"));
    
            System.out.println(subject.isPermitted("user:create"));

    最后输出true,false

    为什么角色role1获取到了,permission没有获取到呢。

    原因是JdbcRealm里面有个permissionsLookupEnabled默认是false,所以不会查询对应的资源权限,我们在配置文件中打开这个查询。

    #打开permission查询
    jdbcRealm.permissionsLookupEnabled=true

    再查询就是true了。

    自定义Realm

    1 新增MyRealm类直接继承AuthorizingRealm.

    public class MyRealm extends AuthorizingRealm {
    
        //认证信息,
        @Override
        protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
            UsernamePasswordToken upToken = (UsernamePasswordToken) token;
    
            String username = upToken.getUsername();
            String password = new String(upToken.getPassword());
            //模拟用户名密码是否正确
            if(!"zhang".equals(username)){
               throw new UnknownAccountException();
            }
            if(!"123456".equals(password)){
                throw new IncorrectCredentialsException();
            }
            return new SimpleAuthenticationInfo(username,password,getName());
    
        }
    
        //授权
        @Override
        protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
            //获取用户名
            String username = (String)getAvailablePrincipal(principals);
            //模拟从数据库查询出来对应的角色和权限
            Set<String> roles = new HashSet<String>();
            roles.add("role_1");
            roles.add("role_2");
    
            Set<String> permissions = new HashSet<String>();
            permissions.add("user:create");
            permissions.add("user:delete");
    
            SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
            info.setRoles(roles);
            info.setStringPermissions(permissions);
            return info;
        }
    
    
    }

    2,classpath文件下新建shiro-myrealm.ini配置文件

    myrealm= com.nfcm.shiro.Realm.MyRealm
    securityManager.realms=$myrealm

    3,测试

            ShiroUtils.login("classpath:shiro-myrealm.ini","zhang","123456");
    
            Subject subject = SecurityUtils.getSubject();
            //是否通过认证
            System.out.println(subject.isAuthenticated());
            //是否有role1角色
            System.out.println(subject.hasRole("role_1"));
    
            System.out.println(subject.isPermitted("user:create"));

    到这里全部测试通过。

    github代码地址

    https://github.com/cmniefei/shiroparent

  • 相关阅读:
    基础算法:两数之和
    adb常用命令食用方法
    C语言面试题
    C语言经典笔试题目
    嵌入式01 51单片机实验02 sfr和sbit bit和int char
    C语言 01 volatile关键字
    C++ 01 基础知识点
    嵌入式02 STM32 实验11 NVIC和中断总结
    嵌入式02 STM32 实验10 定时器中断
    嵌入式02 STM32 实验09 独立/窗口看门狗
  • 原文地址:https://www.cnblogs.com/nfcm/p/9877415.html
Copyright © 2011-2022 走看看