zoukankan      html  css  js  c++  java
  • 自定义shiro的Realm实现和CredentialsMatcher实现以及Token实现

    Realm是shiro比较核心的接口,简单说它的实现类就是校验用户输入的账号信息的地方.如果想自定义实现一般的配置文件如下:

    <!--自定义Realm 继承自AuthorizingRealm -->
        <bean id="userRealm" class="xxx.UserRealm">
    <!-- 自定义比对器 --> <property name="credentialsMatcher" ref="myCredentialsMatcher"></property> </bean> <!-- 自定义匹配器 继承自SimpleCredentialsMatcher --> <bean id="myCredentialsMatcher" class="xxx.MyCredentialsMatcher"></bean>

    其中类的关键代码:

    public class UserRealm extends AuthorizingRealm {
        
        public UserRealm() {
            super();
        }
        @Override
        protected AuthorizationInfo doGetAuthorizationInfo(
                PrincipalCollection principals) {
            SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
    //这里返回的就是你自定义Token中getPricipal返回的用户信息对象. Object user
    = principals.getPrimaryPrincipal(); ...... return authorizationInfo; } @Override protected AuthenticationInfo doGetAuthenticationInfo( AuthenticationToken authcToken) throws AuthenticationException { Object user = authcToken.getPrincipal();
    //从数据库中查找用户的信息
    UserInfo info = Dao.selectUser(user); ...
    //按照用户的输入的principal信息去数据库中查询,然后封装出比对信息.下面的info.getPwd()代表的就是Credentials信息,一般指的密码 SimpleAuthenticationInfo authenticationInfo
    = new SimpleAuthenticationInfo(user, info.getPwd(), getName()); return authenticationInfo; }
    //自定义matcher,这里就是对比用户的输入的信息封装成的token和按照用户输入的principal(一般就是用户名)从数据库中查询出的信息封装的info信息,一般就是比对他们的Credentials
    public
    class MyCredentialsMatcher extends SimpleCredentialsMatcher { @Override public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) { Object tokenCredentials = getCredentials(token); Object accountCredentials = getCredentials(info); return super.equals(tokenCredentials, accountCredentials); } }

    这里红色的doGetAuthenticationInfo方法是用来按照用户输入的principal信息从数据库中查询,并将结果作为一个比对信息,比对2者的Credentials信息是否一致,比对时将调用比对器的doCredentialsMatch方法进行比对,所以我们可以在realm中配置自定义的比对器,重写此方法来达到自定义比对方法,实现特殊的比对逻辑.尤其是token中封装自定义对象时

    .如果一致则登录成功.而绿色的doGetAuthorizationInfo方法则是作为获取当前用户的角色权限相关信息的方法,此方法中要根据用户信息查询出相关的角色权限信息并封装进去.有了此信息之后就可以根据角色和权限信息进行访问权限的控制了.

    一般直接使用usernamePasswordToken即可,但是由于此默认实现一般存储的为字符串的principal和Credentials信息,如有必要改为存储自定义对象,则可以自定义token来实现,关键代码:

    /* 这里必须说一下,必须要继承UsernamePasswordToken,因为realm实现中有个suports方法,会判断token是否被支持,默认的情况下是只支持UsernamePasswordToken的.如需要完全自定义,则需要单独再realm配置中添加上新的自定义token的类型支持.  */
    public class MyUserToken extends UsernamePasswordToken {
        //这个自定义的属性可以是对象.
        private Object user;
    
        public MyUserToken() {
        }
    
        public MyUserToken(Objectuser) {
            this.user = user;
        }
        @Override
        public Object getPrincipal() {
    //账号信息
    return user; } @Override public Object getCredentials() {
    //校验的信息,其实一般就是指密码
    return user.getPwd(); } }

    在用户登录时关键代码:

           Subject currentUser = SecurityUtils.getSubject();
           UserInfo user = new UserInfo();
           user.setName("aaa");
           user.setPwd("123");
            MyUserToken token = new MyUserToken(user);
            currentUser.login(token);
            if (currentUser.isAuthenticated()) {
              //登录成功
            }else{
              //失败
            }           

    总体的思路为使用自定义的token类将用户输入的信息封装,然后采用token进行login操作.此时shiro将使用token中携带的用户信息调用Realm中自定义的doGetAuthenticationInfo方法进行校验比对.比对成功则登录成功,并会自动将相关角色权限信息封装进去.

  • 相关阅读:
    ZedBoard学习(6)System Generator实现串口通信(一行HDL代码都不用写)
    ZedBoard学习(1)Ubutun下进行串口通信
    Zedboard学习(7)PS下第一个裸奔程序
    激光雷达(一)数据采集C++
    win7/win8下安装Oracle1出错10g,提示“程序异常终止,发生未知错误”解决方法
    XML文件的加密与解密
    三层中最重要的SqlHelper类
    创建桌面快捷方式的语法
    秋招总结 艾尔夏尔
    thoughtworks二面准备 (三) 艾尔夏尔
  • 原文地址:https://www.cnblogs.com/chyu/p/5958720.html
Copyright © 2011-2022 走看看