zoukankan      html  css  js  c++  java
  • 3、Shiro实现认证

    基本概念

    • 身份验证

      即在应用中谁能证明他就是他本人。一般提供如他们的身份ID 一些标识信息来表明他就是他本人,如提供身份证,用户名/密码来证明。

      在 shiro 中,用户需要提供principals(身份)和credentials(证明)给shiro,从而应用能验证用户身份。

    • principals(身份)

      身份,即主体的标识属性,可以是任何东西,如用户名、邮箱等,唯一即可。 一个主体可以有多个principals,但只有一个Primary principals,一般是用户名/密码/手机号。

    • credentials(证明)

      证明/凭证,即只有主体知道的安全值,如密码/数字证书等。 最常见的principals和credentials组合就是用户名/密码了。

    认证流程

    认证流程图

    1、调用Subject.login(token)进行登录,其会自动委托给Security Manager,调用之前必须通过SecurityUtils.setSecurityManager()设置。

    2、Security Manager负责真正的身份验证逻辑,它会委托给Authenticator进行身份验证。

    3、Authenticator才是真正的身份验证者,Shiro API中核心的身份认证入口点,此处可以自定义自己的实现。

    4、Authenticator可能会委托给相应的AuthenticationStrategy进行多Realm身份验证,默认ModularRealmAuthenticator会调用AuthenticationStrategy进行多Realm身份验证。

    5、Authenticator会把相应的token传入Realm,从Realm获取身份验证信息,如果没有返回/抛出异常表示身份验证失败。此处可以配置多个Realm,将按照相应的顺序及策略进行访问。

    入门程序实现认证

    1、创建项目,创建普通的Maven工程。

    2、在pom.xml中导入依赖

    <!-- shiro核心包 -->
    <dependency>
        <groupId>org.apache.shiro</groupId>
        <artifactId>shiro-core</artifactId>
        <version>1.4.0</version>
    </dependency>
    <!-- 日志 -->
    <dependency>
        <groupId>commons-logging</groupId>
        <artifactId>commons-logging</artifactId>
        <version>1.2</version>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-log4j12</artifactId>
        <version>1.6.6</version>
    </dependency>
    

    3、log4j.properties日志配置文件

    log4j.rootLogger=debug, stdout
    log4j.appender.stdout=org.apache.log4j.ConsoleAppender
    log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
    log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m %n
    

    4、在src/java/resources下新建shiro.ini文件

    # 配置用户名和密码
    [users]
    zhangsan=123456
    lisi=123456
    

    5、编写代码实现认证

    package com.coydone.test;
    
    import org.apache.shiro.SecurityUtils;
    import org.apache.shiro.authc.AuthenticationException;
    import org.apache.shiro.authc.UsernamePasswordToken;
    import org.apache.shiro.config.IniSecurityManagerFactory;
    import org.apache.shiro.mgt.SecurityManager;
    import org.apache.shiro.subject.Subject;
    import org.apache.shiro.util.Factory;
    
    public class AuthUserTeat {
        public static void main(String[] args) {
            //1、接收用户名和密码
            String username = "zhangsan";
            String password = "123456";
    
            //2、把用户名和密码封装
            UsernamePasswordToken token = new UsernamePasswordToken(username,password);
    
            //3、创建安全管理器的工厂
            Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
    
            //4、从Factory中得到安全管理器
            SecurityManager securityManager = factory.getInstance();
    
            //5、把securityManager和Subject绑定到当前线程
            SecurityUtils.setSecurityManager(securityManager);
    
            //6、从SecurityUtils中得到subject
            Subject subject = SecurityUtils.getSubject();
    
            //7、去认证
            try {
                subject.login(token);
                System.out.println("认证通过");
            } catch (AuthenticationException e) {
                System.out.println("用户名或密码不正确");
            }
            /*
            catch (IncorrectCredentialsException e) {
                System.out.println("密码不正确");
            } catch (UnknownAccountException e) {
                System.out.println("用户名不存在");
            }
             */
    
            //8、查看认证状态
            System.out.println("认证状态:"+subject.isAuthenticated());
    
            //9、退出
            subject.logout();
            System.out.println("认证状态:"+subject.isAuthenticated());
        }
    }
    

    自定义Realm完成认证

    Shiro默认使用自带的IniRealm,IniRealm从ini配置文件中读取用户的信息,大部分情况下需要从系统的数据库中读取用户信息,所以需要自定义realm。

    最基础的是Realm接口,CachingRealm负责缓存处理,AuthenticationRealm负责认证,AuthorizingRealm负责授权,通常自定义的realm继承AuthorizingRealm。

    1、自定义UserRealm

    package com.coydone.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;
    
    public class UserRealm extends AuthorizingRealm {
    
        //认证
        @Override
        protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
            //1、得到身份
            String username = token.getPrincipal().toString();
            //得到凭证
            //String password = token.getCredentials().toString();
    
            //在shiro里面是先根据用户名把用户对象查询出来,再来做密码匹配
    
            //2,根据用户名到数据库中取出用户信息  如果查询不到 返回null  可以使用service来查
            String password = "123456";//假如从数据库中获取密码为1111
    
            //3,返回认证信息
            /**
             * 参数1:可以传到任意对象,如果登录成功,会调用doGetAuthorizationInfo去授权
             * 参数2:从数据库里面查询出来的密码
             * 参数3:当前类名
             */
            SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(username, password, this.getName());
            return simpleAuthenticationInfo;
        }
        //授权
        @Override
        protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
            return null;
        }
    }
    

    2、配置shiro.ini文件

    # 作全局配置
    [main]
    # 创建UserRealm的对象
    userRealm=com.coydone.realm.UserRealm
    # 创建默认的安全管理器
    securityManager=org.apache.shiro.mgt.DefaultSecurityManager
    # 把userRealm给安全管理器
    securityManager.realms=$userRealm
    

    3、测试(测试代码同上)

    public class AuthUserTeat {}
    
    coydone的博客
  • 相关阅读:
    BZOJ1051 [HAOI2006]受欢迎的牛 强连通分量缩点
    This blog has been cancelled for a long time
    欧拉定理、费马小定理及其拓展应用
    同余基础
    [LeetCode] 73. Set Matrix Zeroes
    [LeetCode] 42. Trapping Rain Water
    [LeetCode] 41. First Missing Positive
    [LeetCode] 71. Simplify Path
    [LeetCode] 148. Sort List
    [LeetCode] 239. Sliding Window Maximum
  • 原文地址:https://www.cnblogs.com/coydone/p/13779964.html
Copyright © 2011-2022 走看看