zoukankan      html  css  js  c++  java
  • Spring 整合Shiro:记住我

    1、登录方法

    /**
         * 执行登录操作
         *
         * @param username
         * @param password
         * @param rememberMe
         * @param model
         * @return
         */
        @Log("登录")
        @RequestMapping("/login")
        String login(String username, String password, Boolean rememberMe, Model model) {
            //判断用户名和密码为空
            if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) {
                model.addAttribute("msg", "用户名和密码不能为空!");
                return "login.html";
            }
    
            // shiro登录步骤
            // 1、获取subject对象
            Subject subject = SecurityUtils.getSubject();
    
            // 2、封装对象
            UsernamePasswordToken token = new UsernamePasswordToken(username, password);
            System.out.println(token.toString());
    
            // 3、执行登录(失败会报异常,需捕获异常)
            // 实际开发中,用户名和密码错误,不给出明确提示
            try {
                // 设置是否记住我
                rememberMe = rememberMe == null ? false : rememberMe;
                // 设置记住我
                token.setRememberMe(rememberMe);
           // 登录 subject.login(token);
    // 这样url会改变为index_v1,不然还会是login return "redirect:/index_v1"; } catch (UnknownAccountException e) {//账号不存在 model.addAttribute("msg", "用户名不存在!"); return "/login"; } catch (LockedAccountException e) {//账户锁定 model.addAttribute("msg", "账户被锁定!"); return "/login"; } catch (IncorrectCredentialsException e) {//密码错误 model.addAttribute("msg", "密码错误!"); return "/login"; } }

    2、ShiroConfig

    /**
     * Copyright (C), 2018-2018, 谪仙科技有限公司
     * FileName ShiroConfig
     * Author wangzhiguo
     * Date 2018-12-25 2:49
     * Description Shiro配置
     * History
     * <author>          <time>          <version>          <desc>
     * wangzhiguo        2018-12-25          版本号              描述
     */
    package com.itgeek.config.shiro.config;
    
    import com.itgeek.config.shiro.realm.Myrealm;
    import org.apache.shiro.codec.Base64;
    import org.apache.shiro.session.mgt.SessionManager;
    import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
    import org.apache.shiro.web.mgt.CookieRememberMeManager;
    import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
    import org.apache.shiro.web.servlet.SimpleCookie;
    import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    import java.util.LinkedHashMap;
    import java.util.Map;
    
    /**
     * 〈功能描述〉
     * Shiro配置
     * <p>
     * <p>
     * 系统启动,执行顺序
     * realm -- > securityManager -- > filter
     *
     * @author wangzhiguo
     * @date 2018-12-25
     * @since 1.0.0
     */
    
    @Configuration
    public class ShiroConfig {
        /**
         * shiro核心filter
         *
         * @return
         */
        @Bean()
        public ShiroFilterFactoryBean getShiroFilterFactoryBean() {
            System.out.println("Shiro过滤器");
            ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
            // 设置SecurityManager(必须)
            shiroFilterFactoryBean.setSecurityManager(securityManager());
            /**
             * shiro常用过滤器
             * anon:无需认证
             * authc:必须认证
             * user:如果使用rememberMe功能可以直接访问
             * perms:必须得到资源权限可以访问
             * role:必须得到角色权限可以访问
             */
            // LinkedHashMap 可以保持顺序
            Map<String, String> filterMap = new LinkedHashMap<>();
    
            // 1、认证
            filterMap.put("/", "anon");
            filterMap.put("/index", "anon");
    
            filterMap.put("/toLogin", "anon");
            filterMap.put("/login", "anon");
    
            // 2、资源权限
            filterMap.put("/sys/add", "perms[user:edit]");
            // 3、角色权限
    
            // 所有请求都要认证
            // filterMap.put("/**", "authc");
            // 认证或记住我都可以登录
            filterMap.put("/**", "user");
            // 未授权
            shiroFilterFactoryBean.setUnauthorizedUrl("/noAuth");
            // 设置跳转的登录页
            shiroFilterFactoryBean.setLoginUrl("/toLogin");
            // 设置登录成功的页面
            shiroFilterFactoryBean.setSuccessUrl("/index_v1");
            shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);
            return shiroFilterFactoryBean;
        }
    
        /**
         * 安全管理器
         * 缓存注入在这
         *
         * @return
         */
        @Bean()
        public DefaultWebSecurityManager securityManager() {
            System.out.println("Shiro安全管理器");
            DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
            // 设置realm
            securityManager.setRealm(myrealm());
            // session会话
            // securityManager.setSessionManager(sessionManager());
            // 设置记住我
            securityManager.setRememberMeManager(rememberMeManager());
            return securityManager;
        }
    
        /**
         * realm:自定义的认证和授权逻辑
         *
         * @return
         */
        @Bean()
        public Myrealm myrealm() {
            System.out.println("自定义Realm");
            return new Myrealm();
        }
    
        /**
         * 记住我
         *
         * @return
         */
        @Bean
        public CookieRememberMeManager rememberMeManager() {
            System.out.println("记住我:rememberMe");
            CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();
            cookieRememberMeManager.setCookie(rememberMeCookie());
            //这个地方有点坑,不是所有的base64编码都可以用,长度过大过小都不行,没搞明白,官网给出的要么0x开头十六进制,要么base64
            cookieRememberMeManager.setCipherKey(Base64.decode("4AvVhmFLUs0KTA3Kprsdag=="));
            return cookieRememberMeManager;
        }
    
        /**
         * Cookie管理
         * 创建记住我cookie
         *
         * @return
         */
        @Bean
        public SimpleCookie rememberMeCookie() {
            System.out.println("rememberMeCookie");
            SimpleCookie cookie = new SimpleCookie("rememberMe");
            cookie.setHttpOnly(true);
            // 声明周期
            cookie.setMaxAge(1 * 60 * 60);
            return cookie;
        }
    }

    3、登录页面

    <form action="/login" method="post">
            <span style="color: red" th:text="${msg}"></span>
            <br>
            姓名<input type="text" name="username"> <br>
            密码<input type="password" name="password"> <br>
            记住我<input type="checkbox" checked="checked" name="rememberMe"> <br>
            <button type="submit">登录</button>
        </form>

     4、登录(记住我),会生成rememberMe CookIe

    不记住我:rememberMe Cookie 不会生成

    注销(SHiro:/logout)也会清除rememberMe Cookie

  • 相关阅读:
    转:HTTP Get请求URL最大长度
    Android Paint Xfermode 学习小结
    转:Android-apt
    ajax方法携带授权标识
    获取iframe(angular 动态页面)高度
    IIS下配置跨域设置Access-Control-Allow-Origin
    Oracle 创建 Schema
    定时任务服务 CronService使用说明
    使用ADO.NET执行SQL脚本
    Nuget很慢,我们该怎么办
  • 原文地址:https://www.cnblogs.com/wangzh1guo/p/10176630.html
Copyright © 2011-2022 走看看