Shiro实现记住我功能

本文最后更新于 2024年10月11日 晚上

1.ShiroConfig

1.1.设置权限

页面想要实现记住我功能需要在将访问权限设置成user,如果设置成authc也是会被拦截的。

Filter Name 功能
anno 不需要授权、登录就可以访问
authc 需要登录授权才能访问
authcBasic Basic HTTP身份验证拦截器
perms 授权拦截器perm[‘user:create’]
port 端口拦截器eg:port[80]
rest rest风格拦截器
roles 角色拦截器。eg:role[administrator]
ssl ssl拦截器。通过https协议才能通过
user 用户拦截器。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager securityManager) {
ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();
factoryBean.setSecurityManager(securityManager);

// 权限设置
Map<String, String> filterMap = new LinkedHashMap<>();
filterMap.put("/admin", "user");
filterMap.put("/admin/**", "user");

factoryBean.setFilterChainDefinitionMap(filterMap);
factoryBean.setLoginUrl("/login");
return factoryBean;
}

2.编写cookie的生成模板

1
2
3
4
5
6
7
8
9
10
11
12
13
/**
* cookie对象;
* rememberMeCookie()方法是设置Cookie的生成模版,比如cookie的name,cookie的有效时间等等。
* @return
*/
@Bean
public SimpleCookie rememberMeCookie(){
//这个参数是cookie的名称,对应前端的checkbox的name = rememberMe
SimpleCookie simpleCookie = new SimpleCookie("rememberMe");
//<!-- 记住我cookie生效时间 ,单位秒;-->
simpleCookie.setMaxAge(60*60*24);
return simpleCookie;
}

3.生成cookie加密的密钥

该密钥需要放到cookie管理器中,可以在项目的test中测试生成再复制到cookie管理器。

1
2
3
4
5
6
7
8
9
@Test
void contextLoads() throws NoSuchAlgorithmException {

// cookie加密的密钥
KeyGenerator keygen = KeyGenerator.getInstance("AES");
SecretKey deskey = keygen.generateKey();
System.out.println(Base64.encodeToString(deskey.getEncoded()));

}

4.编写cookie管理对象

1
2
3
4
5
6
7
8
9
10
11
12
13
/**
* cookie管理对象;
* rememberMeManager()方法是生成rememberMe管理器,而且要将这个rememberMe管理器设置到securityManager中
* @return
*/
@Bean
public CookieRememberMeManager rememberMeManager(){
CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();
cookieRememberMeManager.setCookie(rememberMeCookie());
//rememberMe cookie加密的密钥 建议每个项目都不一样 默认AES算法 密钥长度(128 256 512 位)
cookieRememberMeManager.setCipherKey(Base64.decode("uAo6JbB7pRecRI1/6DpZyw=="));
return cookieRememberMeManager;
}

5.将cookie管理器放入securityManager中

1
2
3
4
5
6
7
@Bean
public DefaultWebSecurityManager securityManager() {
DefaultWebSecurityManager manager = new DefaultWebSecurityManager();
manager.setRealm(userRealm());
manager.setRememberMeManager(rememberMeManager());
return manager;
}

2.Controller

在参数中加入boolean rememberMe来获取前端页面发送的是否开启记住我功能,然后在生成token时将rememberMe也放进去。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@PostMapping("/login")
public String login(String username, String password, boolean rememberMe,
Model model) {

Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken(username, password, rememberMe);
try {
subject.login(token);
return "admin/index";
} catch (AuthenticationException e) {
e.printStackTrace();
model.addAttribute("msg","用户名或密码错误!");
return "login";
}

}

3.前端页面

需要在form表单中加入一个单选框,name属性为rememberMe。

1
<input type="checkbox" name="rememberMe">

Shiro实现记住我功能
https://quanht.top/posts/4e2b99f6/
作者
Quanht
发布于
2024年9月28日
许可协议