自定义认证

一.分析

1.验证用户名

最终指向用户名比较是在SimpleAccountRealm类中,doGetAuthenticationInfo方法完成用户名校验。【需要重写方法,完成数据库校验】

2.验证密码

最终密码校验是在AuthenticatingRealm类中,assertCredentialsMatch方法完成校验。【自动校验】

二.总结

1.认证realm【继承AuthenticatingRealm类】

需要重写doGetAuthenticationInfo方法

2.授权realm【继承AuthorizingRealm类】

需要重写doGetAuthorizationInfo方法

三.范例一【测试工作流程】

1.代码块

package com.fengmo;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.realm.text.IniRealm;
import org.apache.shiro.subject.Subject;
/**
 * 测试shiro执行流程
 */
public class TestAuthenticator {
    public static void main(String[] args) {
        //1.创建安全管理器对象securityManager
        DefaultSecurityManager securityManager = new DefaultSecurityManager();
        //2.给安全管理器设置realm
        securityManager.setRealm(new IniRealm("classpath:shiro.ini"));
        //3.SecurityUtils 给全局安全工具类【框架自带】设置安全管理器
        SecurityUtils.setSecurityManager(securityManager);
        //4.获取当前主体的对象【访问用户】
        Subject subject = SecurityUtils.getSubject();
        //5.创建令牌【身份信息,凭证信息】
        UsernamePasswordToken token = new UsernamePasswordToken("xiaochen","123");
        try {
            //6.用户认证
            subject.login(token);   //放置令牌
            System.out.println("认证状态:"+ subject.isAuthenticated());
        }catch (UnknownAccountException e){//认证失败则会发生异常
            e.printStackTrace();
            System.out.println("该异常是用户名不存在");
        }catch (IncorrectCredentialsException e){
            e.printStackTrace();
            System.out.println("该异常是密码错误");
        }
    }
}

2.范例

图片

四.范例二【测试自定义认证】

1.说明

MD5算法:

1.作用:一般用于加密或者签名(校验和)

2.特点:MD5算法不可逆,如何内容相同无论执行多少次md5生成结果始终是一致

3.生成结果:始终是一个16进制32位长度字符串

4.加密时选择MD5+Salt(盐)

2.自定义realm实现

(1)代码块

package com.relam;
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 CustomerRealm extends AuthorizingRealm {
    //这是授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        return null;
    }
    //这是认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        //从token获取用户名
        String principal = (String)token.getPrincipal();
//        System.out.println(principal);  //测试是否获取到身份信息
        //总结:身份信息可以通过JDBC、Mybatis到数据库查询
        //测试查询通过写法
        if("xiaochen".equals(principal)){
            //创建AuthenticationInfo的实现类
            //参数为数据库中的用户名,密码,第三个参数为realm的名字
//            SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo("xiaochen","123",this.getName());
            //第二种写法:由于查询数据库靠principal对象,所以可以直接写成
            SimpleAuthenticationInfo authenticationInfo2 = new SimpleAuthenticationInfo(principal,"123123",this.getName());
            return authenticationInfo2;
        }
        return null;
    }
}

(2)范例

图片

3.测试类

(1)代码块

package com.fengmo;
import com.relam.CustomerRealm;
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.mgt.DefaultSecurityManager;
import org.apache.shiro.subject.Subject;
/**
 * 测试重写自定义认证
 */
public class TestAuthenticator2 {
    public static void main(String[] args) {
        //创建security Manager
        DefaultSecurityManager securityManager = new DefaultSecurityManager();
        //设置自定义realm
        securityManager.setRealm(new CustomerRealm());
        //将安全工具类设置安全管理器
        SecurityUtils.setSecurityManager(securityManager);
        //通过安全工具类获取subject
        Subject subject = SecurityUtils.getSubject();
        //创建令牌
        UsernamePasswordToken token = new UsernamePasswordToken("xiaochen", "123123");
        //认证
        try{
            //认证
            subject.login(token);   //这里调用自定义认证
            System.out.println("验证认证结果"+subject.isAuthenticated());
        }catch (UnknownAccountException e){     //用户名不存在
            e.printStackTrace();
            System.out.println("用户名错误");
        }catch (IncorrectCredentialsException e2){  //密码错误
            e2.printStackTrace();
            System.out.println("密码错误");
        }
    }
}

(2)范例

图片

五.源码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值