• shiro学习笔记_0600_自定义realm实现授权


    博客shiro学习笔记_0400_自定义Realm实现身份认证 介绍了认证,这里介绍授权。

    1,仅仅通过配置文件来指定权限不够灵活且不方便。在实际的应用中大多数情况下都是将用户信息,角色信息,权限信息 保存到了数据库中。所以需要从数据库中去获取相关的数据信息。可以使用 shiro 提供的JdbcRealm来实现,,也可以自定义realm来实现。使用jdbcRealm往往也不够灵活。所以在实际应用中大多数情况都是自定义Realm来实现。

    2,自定义Realm 需要继承 AuthorizingRealm。

    例子程序:

    新建maven项目:

    maven依赖:

    <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-core</artifactId> 
            <version>1.3.2</version> 
        </dependency> 
        
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.2</version>
        </dependency>  
        
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        
        <dependency>  
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId> 
            <version>1.7.5</version>
        </dependency> 
         
        <dependency>
            <groupId>com.mchange</groupId>
            <artifactId>c3p0</artifactId>
            <version>0.9.5.2</version>
        </dependency>
        
        <dependency> 
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.31</version>
        </dependency>

    shiro.ini配置:

    [main]
    userRealm=com.lhy.realm.UserRealm
    securityManager.realm=$userRealm

    log4j.properties:

    log4j.rootLogger=info, stdout
    log4j.appender.stdout=org.apache.log4j.ConsoleAppender
    log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
    log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m %n

    userRealm:

    这里没有使用数据库,配置文件shiro.ini里不用配置[users]信息,因为这里在userRealm里的认证方法里的密码是模拟的,实际肯定会去数据库取。

    package com.lhy.realm;
    
    import java.util.ArrayList;
    import java.util.List;
    
    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;
    /**
     * 自定义Realm实现,该Realm类提供了两个方法:
     * 1,doGetAuthenticationInfo:获取认证信息
     * 2,doGetAuthorizationInfo:获取权限信息
     * @author Administrator
     *
     */
    public class UserRealm extends AuthorizingRealm{
    
        //realm接口的方法
        @Override
        public String getName() {
            return "userRealm";
        }
        
        //完成身份认证并返回认证信息
        //如果身份认证失败,返回null
        @Override
        protected AuthenticationInfo doGetAuthenticationInfo(
                AuthenticationToken token) throws AuthenticationException {
            //获取用户输入的用户名
            String username = (String)token.getPrincipal();//获取身份信息
            System.out.println("username----"+username);
            //实际开发是调用service根据用户名去数据库查对应的密码
            //假设获取的密码是1111
            String password = "1111";
            //Object principal, Object credentials, String realmName
            SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(username,password,getName());
            return info;
        } 
        
        //授权的信息
        @Override
        protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
            //主的 身份信息
            String username = principals.getPrimaryPrincipal().toString();
            System.out.println("==========授权===========");
            System.out.println("username ---"+username);
            //根据用户名到数据库查询当前用户对应的权限信息    ---这里模拟
            List<String> permissions = new ArrayList<String>();
            permissions.add("user:add");
            permissions.add("user:delete");
            permissions.add("user:update");
            permissions.add("user:find");
            /*
             * 实现了AuthorizationInfo接口的pojo,内部存的是权限和角色
             */
            SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
            //给当前用户分配权限
            info.addStringPermissions(permissions);
            return info;
        }
    }

    测试程序:

    package com.lhy.shiro;
    
    import org.apache.shiro.SecurityUtils;
    import org.apache.shiro.authc.AuthenticationException;
    import org.apache.shiro.authc.IncorrectCredentialsException;
    import org.apache.shiro.authc.UnknownAccountException;
    import org.apache.shiro.authc.UsernamePasswordToken;
    import org.apache.shiro.config.IniSecurityManagerFactory;
    import org.apache.shiro.mgt.SecurityManager;
    import org.apache.shiro.subject.Subject;
    import org.apache.shiro.util.Factory;
    
    public class userRealmDemo { 
    
        public static void main(String[] args) {
            //1,创建SecurityManager工厂  读取shiro配置文件
            Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
            //2  通过securityManager工厂获取SecurityManager实例
            SecurityManager securityManager = factory.getInstance();
            //3 将SecurityManager 对象设置到运行环境
            SecurityUtils.setSecurityManager(securityManager);
            //4 通过SecurityUtils获取主体subject
            Subject subject = SecurityUtils.getSubject();
            try {
                //5.假设登录名是zhangsan  密码是1111
                UsernamePasswordToken token = new UsernamePasswordToken("zhangsan","1111");
                //6,登录,进行用户身验证 
                subject.login(token);
                //通过subject判断用户是否通过验证
                if(subject.isAuthenticated()){
                    System.out.println("用户登录成功!"); 
                }
            } catch (UnknownAccountException e) {     
                System.out.println("用户名或密码错误!"); 
                e.printStackTrace();
            }catch (IncorrectCredentialsException e) {
                System.out.println("用户名或密码错误!");
                e.printStackTrace();
            }
            
            System.out.println(subject.isPermittedAll("user:add","user:delete","user:update"));
            //7 退出
            subject.logout();   
        
            
        }
    }
  • 相关阅读:
    团队冲刺阶段二(八)
    团队项目事后诸葛亮会议
    团队冲刺阶段二(七)
    团队冲刺阶段二(六)
    团队冲刺阶段二(五)
    团队冲刺阶段二(四)
    HTML5 CSS3
    浮动和渐变色,定位position,元素的层叠顺序
    css盒模型。边框和内外边距
    标签分类与元素转换
  • 原文地址:https://www.cnblogs.com/lihaoyang/p/6663880.html
Copyright © 2020-2023  润新知