• shiro:多realm配置(链式、分支)


    1、多realm配置相关概念

    (1)使用场景、

    当shiro进行权限管理的时候,数据来源于不同的数据源的时候,我们可以给安全管理器配置多个realm

    • 多个数据库
    • 多个数据表

    (2)多个realm的处理方式

    • 链式处理

    多个realm依次进行认证

    • 分支处理

    根据不用的条件从多个realm中选择一个进行认证

    2、链式

    (1)定义多个realm

    ManagerRealm:

    public class ManagerRealm  extends AuthorizingRealm {
        Logger logger= LoggerFactory.getLogger(UserRealm.class);
        @Override
        public String getName(){
            return "ManagerRealm";
        }
        @Override
        protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
            return null;
        }
    
        @Override
        protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
            logger.info("ManagerRealm---doGetAuthenticationInfo");
            UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
            String username=token.getUsername();
            SimpleAuthenticationInfo info=new SimpleAuthenticationInfo(username,"123",getName());
            return info;
        }
    }

    UserRealm:

    public class UserRealm extends AuthorizingRealm {
        Logger logger = LoggerFactory.getLogger(UserRealm.class);
    
        @Override
        public String getName() {
            return "UserRealm";
        }
    
        @Override
        protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
            return null;
        }
    
        @Override
        protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
            logger.info("UserRealm--doGetAuthenticationInfo");
            UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
            String username = token.getUsername();
            SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(username, "123456", getName());
            return info;
        }
    }

    (2)配置realm

    书写配置类将定义的realm配置给安全管理器、配置过滤器:

    @Configuration
    public class ShiroConfig {
        @Bean
        public UserRealm userRealm() {
            UserRealm userRealm = new UserRealm();
            return userRealm;
        }
    
        @Bean
        public ManagerRealm managerRealm() {
            ManagerRealm managerRealm = new ManagerRealm();
            return managerRealm;
        }
    
        @Bean//安全管理器
        public DefaultWebSecurityManager getDefaultWebSecurityManager() {
            DefaultWebSecurityManager defaultSecurityManager = new DefaultWebSecurityManager();
            Collection<Realm> realms = new ArrayList<>();
            realms.add(userRealm());
            realms.add(managerRealm());
            defaultSecurityManager.setRealms(realms);
            return defaultSecurityManager;
        }
    
        @Bean//过滤器
        public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultSecurityManager securityManager) {
            ShiroFilterFactoryBean filter = new ShiroFilterFactoryBean();
            filter.setSecurityManager(securityManager);
            Map<String, String> filterMap = new HashMap<>();
            filterMap.put("/", "anon");//anon表示不拦截(匿名用户可访问)
            filterMap.put("/login.html", "anon");
            filterMap.put("/user/login", "anon");
            filterMap.put("/user/regist", "anon");
            filterMap.put("/index.html", "user");
            filterMap.put("/**", "authc");
            filter.setFilterChainDefinitionMap(filterMap);
            filter.setLoginUrl("/login.html");
            filter.setUnauthorizedUrl("/login.html");
            return filter;
        }
    }

    (3)controller

    页面跳转:

    @Controller
    public class PageController {
        @RequestMapping("/")
        public String Login1(){
            return "login";
        }
        @RequestMapping("/login.html")
        public String Login(){
            return "login";
        }
    }

    用户登录:

    @Controller
    @RequestMapping("user")
    public class UserController {
        Logger logger=  LoggerFactory.getLogger(UserController.class);
        @RequestMapping("login")
        public String login(String username,String password,String loginType){
            logger.info("UserController--login");
            System.out.println(username+password);
            try {
                UsernamePasswordToken token=new UsernamePasswordToken(username,password);
                Subject subject= SecurityUtils.getSubject();
                subject.login(token);
                return "index";
            }catch (Exception e){
                return "login";
            }
        }
    }

    (4)页面

    登录页:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>login</title>
    </head>
    <body>
        <form action="/user/login">
            用户名:<input type="text" name="username"><br>
            密码:<input type="password" name="password"><br>
            <input type="radio" name="loginType" value="User"/>普通用户
            <input type="radio" name="loginType" value="Manager"/>管理员
            <input type="submit" value="登录">
        </form>
    </body>
    </html>

    index页面:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>index</title>
    </head>
    <body>
    <h3>index</h3>
    </body>
    </html>

    (5)测试

    用户:

     管理员:

     这里并没有对用户的身份进行区分

    3、分支

    (1)自定义token

    public class MyToken extends UsernamePasswordToken {
        private String loginType;
        public MyToken(String username, String password, String loginType) {
            super(username, password);
            this.loginType = loginType;
        }
    
        public String getLoginType() {
            return loginType;
        }
    
        public void setLoginType(String loginType) {
            this.loginType = loginType;
        }
    }

    (2)自定义ModularRealmAuthenticator

    public class MyModularRealmAuthenticator extends ModularRealmAuthenticator {
        protected AuthenticationInfo doAuthenticate(AuthenticationToken authenticationToken) throws AuthenticationException {
            this.assertRealmsConfigured();
            Collection<Realm> realms = this.getRealms();
            MyToken token = (MyToken) authenticationToken;
            String loginType = token.getLoginType();
            Collection<Realm> typeRealms = new ArrayList<>();
            for (Realm realm : realms) {
                if (realm.getName().startsWith(loginType)) {
                    typeRealms.add(realm);
                }
            }
            if (typeRealms.size() == 1) {
                return this.doSingleRealmAuthentication(typeRealms.iterator().next(), authenticationToken);
            } else {
                return this.doMultiRealmAuthentication(typeRealms, authenticationToken);
            }
        }
    }

    (3)配置类

    @Configuration
    public class ShiroConfig {
        @Bean
        public MyModularRealmAuthenticator myModularRealmAuthenticator(){
            MyModularRealmAuthenticator myModularRealmAuthenticator=new MyModularRealmAuthenticator();
            return myModularRealmAuthenticator;
        }
    
        @Bean
        public UserRealm userRealm() {
            UserRealm userRealm = new UserRealm();
            return userRealm;
        }
    
        @Bean
        public ManagerRealm managerRealm() {
            ManagerRealm managerRealm = new ManagerRealm();
            return managerRealm;
        }
    
        @Bean//安全管理器
        public DefaultWebSecurityManager getDefaultWebSecurityManager() {
            DefaultWebSecurityManager defaultSecurityManager = new DefaultWebSecurityManager();
            defaultSecurityManager.setAuthenticator(myModularRealmAuthenticator());
            Collection<Realm> realms = new ArrayList<>();
            realms.add(userRealm());
            realms.add(managerRealm());
            defaultSecurityManager.setRealms(realms);
            return defaultSecurityManager;
        }
    
        @Bean//过滤器
        public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultSecurityManager securityManager) {
            ShiroFilterFactoryBean filter = new ShiroFilterFactoryBean();
            filter.setSecurityManager(securityManager);
            Map<String, String> filterMap = new HashMap<>();
            filterMap.put("/", "anon");//anon表示不拦截(匿名用户可访问)
            filterMap.put("/login.html", "anon");
            filterMap.put("/user/login", "anon");
            filterMap.put("/user/regist", "anon");
            filterMap.put("/index.html", "user");
            filterMap.put("/**", "authc");
            filter.setFilterChainDefinitionMap(filterMap);
            filter.setLoginUrl("/login.html");
            filter.setUnauthorizedUrl("/login.html");
            return filter;
        }
    }

    (4)controller

    书写用户登录的controller,这里使用的是自定义token

    @Controller
    @RequestMapping("user")
    public class UserController {
        Logger logger=  LoggerFactory.getLogger(UserController.class);
        @RequestMapping("login")
        public String login(String username,String password,String loginType){
            logger.info("UserController--login");
            System.out.println(username+password);
            try {
                MyToken token=new MyToken(username,password,loginType);
                Subject subject= SecurityUtils.getSubject();
                subject.login(token);
                return "index";
            }catch (Exception e){
                return "login";
            }
        }
    }

    (5)登录页

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>login</title>
    </head>
    <body>
        <form action="/user/login">
            用户名:<input type="text" name="username"><br>
            密码:<input type="password" name="password"><br>
            <input type="radio" name="loginType" value="User" checked/>普通用户
            <input type="radio" name="loginType" value="Manager"/>管理员
            <input type="submit" value="登录">
        </form>
    </body>
    </html>

    登录页可以选择用户的身份

    (6)测试

    以用户的用户名和密码进行登录,身份选择为用户:可以正常发进入index页面

    以用户的用户名和密码进行登录,身份选择为管理员:不能进入index页面

  • 相关阅读:
    C#网页数据采集(三)HttpWebRequest
    C#获取局域网ip
    C#调用Mail发送QQ邮件
    C#操作Excel(NPOI)
    html文字两行后,就用省略号代替剩下的
    js的dom测试及实例代码
    js循环数组(总结)
    黑马vue---61、为什么vue组件的data要是一个函数
    黑马vue---59-60、组件中的data和methods
    黑马vue---31-32、vue过滤器实例
  • 原文地址:https://www.cnblogs.com/zhai1997/p/13757244.html
Copyright © 2020-2023  润新知