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

自定义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();
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的Shiro自定义Realm代码示例: ``` import org.apache.shiro.authc.*; import org.apache.shiro.realm.*; public class MyRealm extends AuthorizingRealm { @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { // 这里实现权限和角色信息的获取和设置,可以从数据库或其他数据源获取 SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo(); authorizationInfo.addRole("admin"); authorizationInfo.addStringPermission("user:create"); return authorizationInfo; } @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { // 这里实现用户认证,可以从数据库或其他数据源获取用户信息进行验证 String username = (String) token.getPrincipal(); String password = new String((char[]) token.getCredentials()); if (!"admin".equals(username)) { throw new UnknownAccountException(); } if (!"password".equals(password)) { throw new IncorrectCredentialsException(); } return new SimpleAuthenticationInfo(username, password, getName()); } } ``` 该自定义Realm实现Shiro的`AuthorizingRealm`接口,实现了权限和角色信息的获取和设置,以及用户认证的方法。其中,`doGetAuthorizationInfo`方法用于获取用户的角色和权限信息,并将其封装到`AuthorizationInfo`对象中返回;`doGetAuthenticationInfo`方法用于验证用户的身份和凭证信息,并将其封装到`AuthenticationInfo`对象中返回。在这个简单的示例中,认证信息被硬编码为了"admin"和"password",实际使用时应该从数据库或其他数据源中获取。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值