ICode9

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

shiro使用自定义realm实现数据认证

2021-09-09 17:32:18  阅读:126  来源: 互联网

标签:realm 自定义 authc org apache import shiro


自定义realm实现数据认证

在开发中,有时会与一些nosql或者其他地方保存的数据进行认证,这时候,shiro定义的那些realm类可能不能满足实际的功能需求,这时候我们可以通过自定义一个realm来沟通这些数据。实现认证和权限控制。

首先自定义一个realm,继承自AuthorizingRealm抽象类,并实现它的两个功能:

package com.yinhai.realm;

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.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;

/**
 * 自定义Realm
 */
public class CoustomRealm  extends AuthorizingRealm {
    //做授权管理的
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        return null;
    }

    //做认证的
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
         //拿到account
        String principal = (String) token.getPrincipal();

        if("zhangsan".equals(principal)){ //模拟在数据库中查找用户名的过程,如果找到有,则将用户名和密码返回,没有直接返回null
            //通过用户名在数据库中拿到正确的密码,我这里直接省略
            String password = "123456";
            //新建一个返回信息返回给manager,manager会根据正确的账户和密码自动匹配用户传递过来的账户和密码,参数3是当前realm的名称,底			    层会自动生成的。
            SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(principal, password, this.getName());
            return simpleAuthenticationInfo;
        }


        return null;
    }
}

然后就可以使用这个realm了:

package com.yinhai;

import com.yinhai.realm.CoustomRealm;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.subject.Subject;

/**
 * 使用自定义realm进行认证测试
 */
public class CostumeRealmAuthTest {
    public static void main(String[] args) {
        DefaultSecurityManager securityManager = new DefaultSecurityManager();
        securityManager.setRealm(new CoustomRealm());
        SecurityUtils.setSecurityManager(securityManager);
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken zhangsan = new UsernamePasswordToken("zhangsan", "123456");
        try{
            subject.login(zhangsan);
            System.out.println(subject.isAuthenticated());
        }catch (Exception e){
            e.getMessage();
        }
    }
}

以上是普通的,明文密码匹配方式认证,如果要使用加密的话可以采用以下:

package com.yinhai.realm;

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.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;

public class CostumeMD5Realm extends AuthorizingRealm {
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        return null;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        //拿到account
        String principal = (String) token.getPrincipal();

        if("zhangsan".equals(principal)){ //模拟在数据库中查找用户名的过程,如果找到有,则将用户名和密码返回,没有直接返回null
            //通过用户名在数据库中拿到正确的密码,我这里直接省略
            String password = "458e4c8450daf785d77e92c6d391e6a2";
            //新建一个返回信息返回给manager,manager会根据正确的账户和密码自动匹配用户传递过来的账户和密码,
            // 参数3是盐加密规则
            // 参数4是当前realm的名称,底层会自动生成的。
            SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(principal,
                    password,
                    ByteSource.Util.bytes("07?*xx"),
                    this.getName());
            return simpleAuthenticationInfo;
        }


        return null;
    }
}

使用:

package com.yinhai;

import com.yinhai.realm.CostumeMD5Realm;
import com.yinhai.realm.CoustomRealm;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.subject.Subject;

public class CostumeMD5RealmAuthTest {
    public static void main(String[] args) {
        DefaultSecurityManager securityManager = new DefaultSecurityManager();
        CostumeMD5Realm costumeMD5Realm = new CostumeMD5Realm();
        //获取密码匹配器
        HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
        //设置加密方式
        hashedCredentialsMatcher.setHashAlgorithmName("MD5");
        //设置hash散列次数
        hashedCredentialsMatcher.setHashIterations(512);
        //设置自定义realm的密码匹配器
        costumeMD5Realm.setCredentialsMatcher(hashedCredentialsMatcher);

        securityManager.setRealm(costumeMD5Realm);
        SecurityUtils.setSecurityManager(securityManager);
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken zhangsan = new UsernamePasswordToken("zhangsan", "123456");
        try{
            subject.login(zhangsan);
            System.out.println(subject.isAuthenticated());
        }catch (Exception e){
            e.getMessage();
        }
    }
}

标签:realm,自定义,authc,org,apache,import,shiro
来源: https://blog.csdn.net/hubertbb3/article/details/120204441

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

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

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

ICode9版权所有