JAVA全系列 教程
3762个小节阅读:7093.8k
目录
C语言快速入门
JAVA全系列 教程
面向对象的程序设计语言
Python全系列 教程
Python3.x版本,未来主流的版本
人工智能 教程
顺势而为,AI创新未来
大厂算法 教程
算法,程序员自我提升必经之路
C++ 教程
一门通用计算机编程语言
微服务 教程
目前业界流行的框架组合
web前端全系列 教程
通向WEB技术世界的钥匙
大数据全系列 教程
站在云端操控万千数据
AIGC全能工具班
A A
White Night
Remember Me为“记住我”功能,即登录成功后,下次访问系统时无需重新登录。当使用“记住我”功能登录后,Shiro会在浏览器Cookie中保存序列化后的认证数据。之后浏览器访问项目时会携带该Cookie数据,这样不登录也可以完成认证。
当然,为了安全起见,并不是所有资源都可以通过“记住我”访问。比如在电商系统中,查询商品等操作可以不登录,但是支付时往往需要重新登录,Shiro支持配置什么资源可以通过“记住我”访问。
实现“记住我”功能的写法如下:
序列化所有实体类
xxxxxxxxxx
@Data
public class Users implements Serializable {
private Integer uid;
private String username;
private String password;
private String salt;
}
配置Cookie生成器和记住我管理器
xxxxxxxxxx
// Cookie生成器
@Bean
public SimpleCookie simpleCookie() {
SimpleCookie simpleCookie = new SimpleCookie("rememberMe");
// Cookie有效时间,单位:秒
simpleCookie.setMaxAge(20);
return simpleCookie;
}
// 记住我管理器
@Bean
public CookieRememberMeManager cookieRememberMeManager(SimpleCookie simpleCookie) {
CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();
// Cookie生成器
cookieRememberMeManager.setCookie(simpleCookie);
// Cookie加密的密钥
cookieRememberMeManager.setCipherKey(Base64.decode("6ZmI6I2j3Y+R1aSn5BOlAA=="));
return cookieRememberMeManager;
}
@Bean
public DefaultWebSecurityManager securityManager(MyRealm myRealm,
MyRealm2 myRealm2,
SessionManager sessionManager,
CookieRememberMeManager rememberMeManager){
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
// 自定义Realm放入SecurityManager中
// securityManager.setRealm(myRealm);
// 设置Realm管理者(需要设置在Realm之前)
securityManager.setAuthenticator(modularRealmAuthenticator());
List<Realm> realms = new ArrayList();
realms.add(myRealm);
// realms.add(myRealm2);
securityManager.setRealms(realms);
securityManager.setSessionManager(sessionManager);
securityManager.setRememberMeManager(rememberMeManager);
return securityManager;
}
修改登录表单
xxxxxxxxxx
<form class="form" action="/user/login" method="post">
<input type="text" placeholder="用户名" name="username">
<input type="password" placeholder="密码" name="password">
<input type="checkbox" name="rememberMe" value="on">记住我<br>
<button type="submit" id="login-button">登录</button>
</form>
修改登录控制器
xxxxxxxxxx
@RequestMapping("/user/login")
public String login(String username, String password,String rememberMe) {
try {
usersService.userLogin(username, password,rememberMe);
return "main";
} catch (DisabledAccountException e) {
System.out.println("账户失效");
return "fail";
} catch (ConcurrentAccessException e) {
System.out.println("竞争次数过多");
return "fail";
} catch (ExcessiveAttemptsException e) {
System.out.println("尝试次数过多");
return "fail";
} catch (UnknownAccountException e) {
System.out.println("用户名不正确");
return "fail";
} catch (IncorrectCredentialsException e) {
System.out.println("密码不正确");
return "fail";
} catch (ExpiredCredentialsException e) {
System.out.println("凭证过期");
return "fail";
}
}
修改登录Service
xxxxxxxxxx
@Service
public class UsersService {
@Autowired
private DefaultWebSecurityManager securityManager;
public void userLogin(String username,String password,String rememberMe) throws AuthenticationException {
SecurityUtils.setSecurityManager(securityManager);
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token=new UsernamePasswordToken(username,password);
if (rememberMe != null){
// 如果用户选择记住我,则生成记住我Cookie
token.setRememberMe(true);
}
subject.login(token);
}
}
配置过滤器,配置可以通过“记住我”访问的资源。
xxxxxxxxxx
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultWebSecurityManager securityManager){
// 1.创建过滤器工厂
ShiroFilterFactoryBean filterFactory=new ShiroFilterFactoryBean();
// 2.过滤器工厂设置SecurityManager
filterFactory.setSecurityManager(securityManager);
// 3.设置shiro的拦截规则
Map<String,String> filterMap=new HashMap<>();
// 不拦截的资源
filterMap.put("/login.html","anon");
filterMap.put("/fail.html","anon");
filterMap.put("/user/login","anon");
filterMap.put("/static/**","anon");
// 其余资源都需要认证,authc过滤器表示需要认证才能进行访问; user过滤器表示配置记住我或认证都可以访问
// filterMap.put("/**","authc");
filterMap.put("/user/pay","authc");
filterMap.put("/**", "user");
// 4.将拦截规则设置给过滤器工厂
filterFactory.setFilterChainDefinitionMap(filterMap);
// 5.登录页面
filterFactory.setLoginUrl("/login.html");
return filterFactory;
}
编写支付控制器
xxxxxxxxxx
// 支付
@RequestMapping("/user/pay")
@ResponseBody
public String pay(){
return "支付功能";
}
实时效果反馈
1. 在Shiro中,user
过滤器表示
A 无需认证即可访问
B 需要登录认证才能访问
C 需要登录认证或记住我认证才能访问
D 需要特定权限才能访问
2. 在Shiro中,"记住我"管理器对象为
A CookieRememberMe
B CookieRememberManager
C RememberMeManager
D CookieRememberMeManager
答案
1=>C 2=>D