使用shiro完成认证

代码

1.先不用数据库来进行身份认证,--我们ini文件,window系统文件,该文件中可以存放账号和密码。

(1) 创建一个maven java工程

 <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-core</artifactId>
            <version>1.9.0</version>
        </dependency>

(2)创建ini文件

(3)测试代码

public class TestShiro01 {
    public static void main(String[] args) {
        //1.获取SecutiryManager对象
        DefaultSecurityManager securityManager = new DefaultSecurityManager();
        //2.读取ini文件
        IniRealm iniRealm = new IniRealm("classpath:shiro.ini");
        //3.设置securityManager的realm
        securityManager.setRealm(iniRealm);
        //4. 设置securityManager上下文生效
        SecurityUtils.setSecurityManager(securityManager);

        //5. 获取subject主体对象
        Subject subject= SecurityUtils.getSubject();
        try {
            //UsernamePasswordToken作用就是封装你输入的账号和密码 是客户输入的账号和密码
            UsernamePasswordToken token=new UsernamePasswordToken("zhangsan","123456");
            //抛出异常 比对shiro中realm把你自带对比
            subject.login(token);
            System.out.println("登录成功");
        }catch (Exception e){
            e.printStackTrace();
            System.out.println("账号或密码错误");
        }
}
}

 

认证的原理

 

Subject: 主题 登录信息提交给SecurityManager, --->认证器Authenticator---->根据你的realm提供的数据进行相关的认证。 realm---与数据源交互的类。

授权

 

 

 修改ini文件

修改代码

public class TestShiro01 {
    public static void main(String[] args) {
        //1.获取SecutiryManager对象
        DefaultSecurityManager securityManager = new DefaultSecurityManager();
//        //2.读取ini文件
        IniRealm iniRealm = new IniRealm("classpath:shiro.ini");
        //3.设置securityManager的realm
        securityManager.setRealm(iniRealm);
        //4. 设置securityManager上下文生效
        SecurityUtils.setSecurityManager(securityManager);

        //5. 获取subject主体对象
        Subject subject= SecurityUtils.getSubject();
        try {
            //UsernamePasswordToken作用就是封装你输入的账号和密码 是客户输入的账号和密码
            UsernamePasswordToken token=new UsernamePasswordToken("zhangsan","123456");
            //抛出异常 比对shiro中realm把你自带对比
            subject.login(token);
            System.out.println("登录成功");
        }catch (Exception e){
            e.printStackTrace();
            System.out.println("账号或密码错误");
        }
       // subject.logout();
        System.out.println("====================================================登录后=====================================");
        boolean authenticated = subject.isAuthenticated();
        if(authenticated){
            //判断当前登录者是否具有user:query权限
            boolean permitted = subject.isPermitted("user:update");
            System.out.println(permitted);
            //从角色角度
            boolean b = subject.hasRole("role1");
            System.out.println(b);
        }else{
            System.out.println("请先认证");
        }
    }
}

 

认证的底层源码。

 

 

我们分析源码 我们的最终认证交于realm完成认证功能,返回一个info, 如果info不为null,则进行密码比对。如果我们希望用数据库中的账号和密码完成认证功能,则只需要我们自定义一个类并继承AuthenticatingRealm。

自定义Realm 认证

public class MyRealm extends AuthenticatingRealm {
    private UserService userService=new UserService();
    //该方法用于完成认证的功能
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        //1.根据token获取账号
        String username = (String) authenticationToken.getPrincipal();
        //2.根据账号查询用户信息
        User user = userService.findByUsername(username);
        if(user!=null){
            //从数据库中获取的密码
            SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user,user.getPassword(),this.getName());
            return info;
        }
        return null;
    }
}

 

加密

shiro它提供了很多中加密器。其他使用最多就是HashedCredentialsMatcher。它的底层使用的还是Md5加密。了解一下MD5加密

public class Test03 {
    public static void main(String[] args) {
        //source:需要加密的明文
        Md5Hash md5Hash = new Md5Hash("123456");
        System.out.println(md5Hash);//e10adc3949ba59abbe56e057f20f883e密文---默认md5加密是不可逆的。但是网上由一些破解软件

        //salt:盐
        Md5Hash md5Hash1=new Md5Hash("123456","abc?!");
        System.out.println(md5Hash1);

        //设置n次加密
        Md5Hash md5Hash2 = new Md5Hash("123456","abc?!",1024);

    }
}

shiro使用密码加密器

修改realm代码

 

自定义realm的授权功能

public class MyRealm extends AuthorizingRealm {
    private UserService userService = new UserService();
    //什么时候执行该方法: 当你进行权限校验时会执行该方法
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
       User user = (User) principalCollection.getPrimaryPrincipal();
        //根据账号查询该用户具有哪些权限
        List<String> list= userService.findPermissionByUsername(user.getUsername());
        if(list!=null&&list.size()>0){
            SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();
            info.addStringPermissions(list);
            return info;
        }
        return null;
    }

    //
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        //1.根据token获取账号
        String username = (String) authenticationToken.getPrincipal();
        //2.根据账号查询用户信息
        User user = userService.findByUsername(username);
        if(user!=null){
            //从数据库中获取的密码
            ByteSource credentialsSalt=ByteSource.Util.bytes(user.getSalt());
            SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user,user.getPassword(),credentialsSalt,this.getName());
            return info;
        }
        return null;
    }
}

 测试:

public class TestShiro04 {
    public static void main(String[] args) {
        DefaultSecurityManager securityManager=new DefaultSecurityManager();

        MyRealm myRealm=new MyRealm();
        HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();
        credentialsMatcher.setHashAlgorithmName("MD5");
        credentialsMatcher.setHashIterations(1024);
        myRealm.setCredentialsMatcher(credentialsMatcher);

        securityManager.setRealm(myRealm);

        SecurityUtils.setSecurityManager(securityManager);


        Subject subject = SecurityUtils.getSubject();

        try {
            UsernamePasswordToken token = new UsernamePasswordToken("ykq", "123456");
            subject.login(token);

            System.out.println(subject.isPermitted("user:query"));
            System.out.println(subject.isPermitted("user:update"));

        }catch (Exception e){
            System.out.println("账号密码错误");
        }

    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值