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

最新文章

  1. Java实验四
  2. [Eclipse] - eclipse集成jboss7.1
  3. Spring声明式事务管理基于tx/aop命名空间
  4. Maven项目自动生成mybaties配置文件
  5. [学习笔记] 七步从Angular.JS菜鸟到专家(3):数据绑定和AJAX [转]
  6. c++的输入流基础知识
  7. EXTJS 4.2 资料 控件之checkboxgroup的用法(动态数据)
  8. hdu3681--Prison Break(TSP+二分)
  9. WM_DRAWITEM与DrawItem()的讨论(自绘)
  10. 读书笔记-你不知道的JavaScript(上)
  11. 【CSS3】颜色表示方式
  12. python3 第二十章 - 函数式编程之Higher-order function(高阶函数)
  13. tree、find、tail命令重要实战
  14. (五) vivi代码分析
  15. Hadoop 安全模式safemode
  16. 升级openssl 操作记录
  17. CSS3笔记2
  18. STL之Set和multiset容器
  19. 实战--利用SVM对基因表达标本是否癌变的预测
  20. python输入与输出165

热门文章

  1. H5-移动端适配
  2. HDU 2276 Kiki &amp; Little Kiki 2( 矩阵快速幂 + 循环同构矩阵 )
  3. $attr和$listeners is readonly
  4. MyBatis学习总结(5)——实现关联表查询
  5. 在IDEA中代码自动提示第一个字母大小写必须匹配的解决
  6. c3p0在spring中的配置
  7. D3js-绘制地图时出现过小, 设置scale还是无效 的解决方法
  8. 50.AngularJs directive详解及示例代码
  9. requireJS实现原理分析
  10. Parquet学习总结