Shiro入门学习之自定义Realm实现认证(四)

一、概述

  Shirom默认使用自带的IniRealm,IniRealm从ini配置文件中读取用户的信息,而大部分情况下需要从系统数据库中读取用户信息,所以需要实现自定义Realm,Realm接口如下:

 由此可以分析

  ①CachingRealm:负责缓存处理

  ②AuthenticationRealm:负责认证

  ③AuthorizingRealm:负责授权

通常情况下,自定义的Realm继承AuthorizingRealm即可实现认证与授权

二、自定义Realm实现认证

1、新建module,添加如下pom依赖

 <properties>
        <shiro.version>1.4.1</shiro.version>
        <loggingg.version>1.2</loggingg.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-core</artifactId>
            <version>${shiro.version}</version>
        </dependency>
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>${loggingg.version}</version>
        </dependency>
    </dependencies>

2、自定义Realm类

public class UserRealm extends AuthenticatingRealm
{
    private UserService userService= new UserServiceImpl();
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException
    {
        String username = token.getPrincipal().toString();
        System.out.println("自定义Realm:"+username);
        /**
         * Shiro认证流程是根据用户名将用户对象查询出来,再做密码匹配
         */
        User user = userService.queryUserByUserName(username);
        if (user!=null)
        {
            /**
             * 参数说明
             * 参数1:可以传任意对象(可以通过subject.getPrincipal()获取该参数)
             * 参数2:数据库中的用户密码
             * 参数3:当前类名
             */
            new SimpleAuthenticationInfo();
            SimpleAuthenticationInfo info = new SimpleAuthenticationInfo("fafafajsfjslkdfksdf", user.getPwd(), this.getName());
            return info;
        }
        else {
            return null;
        }
    }
}

3、test类

public class TestAuthenticationRealm
{
    public static void main(String[] args)
    {
        //1.模拟前台传递的用户名和密码
        String username = "zhangsan";
        String password = "123456";
        //2.创建安全管理器的工厂
        Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
        //3.通过安全管理器工厂获取安全管理器
        DefaultSecurityManager securityManager = (DefaultSecurityManager)factory.getInstance();
        //4.创建自定义的Realm
        UserRealm userRealm = new UserRealm();
        //5.设置自定义的Realm
        securityManager.setRealm(userRealm);
        //6.将安全管理器绑定到当前运行环境
        SecurityUtils.setSecurityManager(securityManager);
        //7.从当前环境中获取Subject主体
        Subject subject1 = SecurityUtils.getSubject();
        //8.调用主体的登录方法
        try
        {
            subject1.login(new UsernamePasswordToken(username,password));
            System.out.println("登录成功~");

            Object principal = subject1.getPrincipal();
            System.out.println(principal);

        } catch (IncorrectCredentialsException e) {
            System.out.println("密码不正确");
        }catch (UnknownAccountException e) {
            System.out.println("用户名不存在");
        }

    }
}

三、分析

1、SecurityManager如何设置自定义的Realm?

  SecurityManger不能直接setRealm,输出其结果发现默认实现类是DefaultSecurityManager,通过强转该类,调用setRealm方法设置自定义的Realm

2、自定义Realm的分析

  参数1可以为任意参数,可以通过subject.getPrincipal()获取该参数

subject.getPrincipal()获取该参数

 

 3、通过shiro.ini配置自定义的Realm

 test类中需要注释以下2行:

四、总结

1、面向接口编程:可以发现处处是接口

2、SecurityManager接口的实现类是DefaultSecurityManager,通过该类的setRealm设置自定义的Realm

3、SimpleAuthenticationInfo的重载方法(参数1可以为任意对象,数据库查询密码,当前类名),可以通过subject.getPrincipal()获取参数1(很重要!

posted @ 2019-10-30 20:54  coder、  阅读(471)  评论(0编辑  收藏  举报