zoukankan      html  css  js  c++  java
  • 多realm以及jdbcRealm配置

    多realm配置

    public class MyRealm1 implements Realm {
    
    
        public String getName() {
            return "myrealm1";
        }
        public boolean supports(AuthenticationToken token) {
            return token instanceof UsernamePasswordToken; //仅支持UsernamePasswordToken类型的Token
        }
        public AuthenticationInfo getAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
    
            String username = (String)token.getPrincipal();  //得到用户名
            String password = new String((char[])token.getCredentials()); //得到密码
            if(!"zhang".equals(username)) {
                throw new UnknownAccountException(); //如果用户名错误
            }
            if(!"123".equals(password)) {
                throw new IncorrectCredentialsException(); //如果密码错误
            }
            //如果身份认证验证成功,返回一个AuthenticationInfo实现;
            return new SimpleAuthenticationInfo(username, password, getName());
        }
    }
    
    public class MyRealm2 implements Realm {
    
    
        public String getName() {
            return "myrealm2";
        }
    
    
        public boolean supports(AuthenticationToken token) {
            return token instanceof UsernamePasswordToken; //仅支持UsernamePasswordToken类型的Token
        }
    
    
        public AuthenticationInfo getAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
    
            String username = (String)token.getPrincipal();  //得到用户名
            String password = new String((char[])token.getCredentials()); //得到密码
            if(!"wang".equals(username)) {
                throw new UnknownAccountException(); //如果用户名错误
            }
            if(!"123".equals(password)) {
                throw new IncorrectCredentialsException(); //如果密码错误
            }
            //如果身份认证验证成功,返回一个AuthenticationInfo实现;
            return new SimpleAuthenticationInfo(username, password, getName());
        }
    }
    
    [main]
    #声明一个realm
    myRealm1=com.github.zhangkaitao.shiro.chapter2.realm.MyRealm1
    myRealm2=com.github.zhangkaitao.shiro.chapter2.realm.MyRealm2
    #指定securityManager的realms实现
    securityManager.realms=$myRealm1,$myRealm2
    

    securityManege会按照realm指定顺序进行身份验证,没有指定(securityManager.realms=myRealm1,myRealm2)也可以,那就会按照申明顺序进行使用。当显示指定realm后,其他没有被指定realm会被忽略,如:securityManage.realms=$myRealm1,那么myRealm2就不会被设置进realms。

    @Test
        public void testCustomMultiRealm() {
            //1、获取SecurityManager工厂,此处使用Ini配置文件初始化SecurityManager
            Factory<org.apache.shiro.mgt.SecurityManager> factory =
                    new IniSecurityManagerFactory("classpath:shiro-multi-realm.ini");
    
            //2、得到SecurityManager实例 并绑定给SecurityUtils
            org.apache.shiro.mgt.SecurityManager securityManager = factory.getInstance();
            SecurityUtils.setSecurityManager(securityManager);
    
            //3、得到Subject及创建用户名/密码身份验证Token(即用户身份/凭证)
            Subject subject = SecurityUtils.getSubject();
            UsernamePasswordToken token = new UsernamePasswordToken("wang", "123");
    
            try {
                //4、登录,即身份验证
                subject.login(token);
            } catch (AuthenticationException e) {
                //5、身份验证失败
                e.printStackTrace();
            }
    
            Assert.assertEquals(true, subject.isAuthenticated()); //断言用户已经登录
    
            //6、退出
            subject.logout();
        }
    

    jdbcRealm使用

    [main]
    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=root
    jdbcRealm.dataSource=$dataSource
    securityManager.realms=$jdbcRealm
    

    测试代码同上

    问题记录:

    当使用身份凭证登录后,再获取token信息时,如何设置token中放置的内容?

    查看JdbcRealm类源码,可以看到doGetAuthenticationInfo(AuthenticationToken token)方法返回一个SimpleAuthenticationInfo info= new SimpleAuthenticationInfo(username, password.toCharArray(), this.getName());故而token中只放了username。

    下面这个自定义realm类,在内部查询数据库,综合了自定义realm与jdbcRealm。

    public class SampleRealm extends AuthorizingRealm {
    
        @Autowired
        UUserService userService;
        @Autowired
        PermissionService permissionService;
        @Autowired
        RoleService roleService;
    
        public SampleRealm() {
            super();
        }
    
        /**
         * 认证信息,主要针对用户登录,
         */
        protected AuthenticationInfo doGetAuthenticationInfo(
                AuthenticationToken authcToken) throws AuthenticationException {
    
            ShiroToken token = (ShiroToken) authcToken;
            UUser user = userService.login(token.getUsername(), token.getPswd());
            if (null == user) {
                throw new AccountException("帐号或密码不正确!");
                /**
                 * 如果用户的status为禁用。那么就抛出<code>DisabledAccountException</code>
                 */
            } else if (UUser._0.equals(user.getStatus())) {
                throw new DisabledAccountException("帐号已经禁止登录!");
            } else {
                //更新登录时间 last login time
                user.setLastLoginTime(new Date());
                userService.updateByPrimaryKeySelective(user);
            }
            return new SimpleAuthenticationInfo(user, user.getPswd(), getName());
        }
    
        /**
         * 授权
         */
        @Override
        protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
    
            Long userId = TokenManager.getUserId();
            SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
            //根据用户ID查询角色(role),放入到Authorization里。
            Set<String> roles = roleService.findRoleByUserId(userId);
            info.setRoles(roles);
            //根据用户ID查询权限(permission),放入到Authorization里。
            Set<String> permissions = permissionService.findPermissionByUserId(userId);
            info.setStringPermissions(permissions);
            return info;
        }
    
        /**
         * 清空当前用户权限信息
         */
        public void clearCachedAuthorizationInfo() {
            PrincipalCollection principalCollection = SecurityUtils.getSubject().getPrincipals();
            SimplePrincipalCollection principals = new SimplePrincipalCollection(
                    principalCollection, getName());
            super.clearCachedAuthorizationInfo(principals);
        }
    
        /**
         * 指定principalCollection 清除
         */
        public void clearCachedAuthorizationInfo(PrincipalCollection principalCollection) {
            SimplePrincipalCollection principals = new SimplePrincipalCollection(
                    principalCollection, getName());
            super.clearCachedAuthorizationInfo(principals);
        }
    }
    

    关键点:doGetAuthenticationInfo(AuthenticationToken token)方法的返回值

    return new SimpleAuthenticationInfo(user, user.getPswd(), getName());所以返回的token是一个user实体。

  • 相关阅读:
    解决Cannot change version of project facet Dynamic web module to 3.0
    mysql 存储过程
    查看建表语句
    mysql query cache 查询缓存
    数据库连接池
    JDBC Statement PrepareStatement
    mysql 改变表结构 alter
    maven 获取pom.xml的依赖---即仓库搜索服务
    windows常用快捷键
    oracle 的数据完整性
  • 原文地址:https://www.cnblogs.com/zailushang1996/p/8660753.html
Copyright © 2011-2022 走看看