• (三)自定义Realm


    一、Realm概念

    • Realm:域,Shiro从从Realm获取安全数据(如用户、角色、权限),就是说SecurityManager要验证用户身份,那么它需要从Realm获取相应的用户进行比较以确定用户身份是否合法;也需要从Realm得到用户相应的角色/权限进行验证用户是否能进行操作;可以把Realm看成DataSource,即安全数据源
    • org.apache.shiro.realm.Realm接口如下:
        String getName(); //返回一个唯一的Realm名字  
        boolean supports(AuthenticationToken token); //判断此Realm是否支持此Token  
        AuthenticationInfo getAuthenticationInfo(AuthenticationToken token)  
         throws AuthenticationException;  //根据Token获取认证信息  

    引入依赖

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.shyroke.www</groupId> <artifactId>firstShiro</artifactId> <packaging>war</packaging> <version>0.0.1-SNAPSHOT</version> <name>firstShiro Maven Webapp</name> <url>http://maven.apache.org</url> <properties> <shiro.version>1.3.2</shiro.version> </properties> <dependencies> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.21</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>jcl-over-slf4j</artifactId> <version>1.7.21</version> <scope>runtime</scope> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.1.7</version> <scope>runtime</scope> </dependency> <!-- Shiro dependencies: --> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-core</artifactId> <version>${shiro.version}</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-web</artifactId> <version>${shiro.version}</version> </dependency> </dependencies> <build> <finalName>firstShiro</finalName> </build> </project>

    自定义的realm MapRealm.java

    package realms;
    
    import java.util.HashMap;
    import java.util.Map;
    import org.apache.shiro.authc.AuthenticationException;
    import org.apache.shiro.authc.AuthenticationInfo;
    import org.apache.shiro.authc.AuthenticationToken;
    import org.apache.shiro.authc.IncorrectCredentialsException;
    import org.apache.shiro.authc.SimpleAuthenticationInfo;
    import org.apache.shiro.authc.UnknownAccountException;
    import org.apache.shiro.authc.UsernamePasswordToken;
    import org.apache.shiro.realm.Realm;
    
    public class MapRealm implements Realm {
        /** * userMap变量:用于存放用户身份和凭证(用户名和密码) */
        private static Map<String, String> userMap;
        static {
            userMap = new HashMap<String, String>();
            userMap.put("user1", "value1");
            userMap.put("user2", "value2");
        }
    
        /** * 该Realm的名字 */
        public String getName() {
            return "mapRealm";
        }
    
        /** * 该Realm支持的token类型 */
        public boolean supports(AuthenticationToken token) {
            return token instanceof UsernamePasswordToken;
        }
    
        public AuthenticationInfo getAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
            String userName = token.getPrincipal().toString();
            String passWord = new String((char[]) token.getCredentials());
            if (!userMap.containsKey(userName))
                throw new UnknownAccountException("用户名错误");
            if (!passWord.equals(userMap.get(userName)))
                throw new IncorrectCredentialsException("密码错误");
            AuthenticationInfo info = new SimpleAuthenticationInfo(userName, passWord, getName());
            return info;
        }
    }

     

    shiro.ini

    [main] mapRealm=realms.MapRealm securityManager.realms=$mapRealm [users] yhj=123 zs=456

     测试类

    package test;
    
    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.config.IniSecurityManagerFactory;
    import org.apache.shiro.mgt.SecurityManager;
    import org.apache.shiro.subject.Subject;
    
    public class TestMain {
        public static void main(String[] args) {
            SecurityManager securityManager = new IniSecurityManagerFactory("classpath:shiro.ini").getInstance();
            SecurityUtils.setSecurityManager(securityManager);
            Subject subject = SecurityUtils.getSubject();
            UsernamePasswordToken token = new UsernamePasswordToken("user2", "value2");
            try {
                subject.login(token);
                System.out.println(token.getUsername() + "	" + new String((char[]) token.getPassword()));
            } catch (UnknownAccountException e) {
                System.out.println(e.getMessage());
            } catch (IncorrectCredentialsException e) {
                System.out.println(e.getMessage());
            }
        }
    }

     

    具体的流程大概是:当程序执行到subject.login(token)时候,执行自定义realm即MapRealm的boolean supports(AuthenticationToken token)方法,如果该Realm支持该token返回true,继续执行MapRealm的AuthenticationInfo getAuthenticationInfo(AuthenticationToken token)方法,如果该Realm不支持该token返回false,抛出异常:ealm [realms.MapRealm@1cd072a9] does not support authentication token [org.apache.shiro.authc.UsernamePasswordToken - user2, rememberMe=false]

    结果:

  • 相关阅读:
    pycharm cannot import name 'imread' from 'scipy.misc报错及解决办法
    顶会热词冲击(二)
    个人总结
    顶会热词冲击(一)
    Android学习——使用http协议访问网络
    python爬取论文
    《程序员修炼之道:从小工到专家》 阅读笔记03
    开课第十四周周总结
    Android学习——播放视频
    Android学习——播放音频
  • 原文地址:https://www.cnblogs.com/shyroke/p/7806950.html
Copyright © 2020-2023  润新知