Apache shiro 简介
Apache Shiro 是一个强大且易用的 Java 安全框架,执行身份验证、授权、密码和会话管理。使用 Shiro 的易于理解的 API,您可以快速、轻松地获得任何应用程序,从最小的移动应用程序到最大的网络和企业应用程序。
本文针对 Shiro 进行了一个原理性的讲解,从源码层面来分析了 Shiro 的认证和授权的整个流程,并在认证与授权的这个流程讲解冲,穿插说明 rememberme 的作用,以及为何该字段会导致反序列化漏洞。
Apache shiro 认证
在该小节中我们将会详细讲解 Shiro 是如何认证一个用户为合法用户的 Shiro 漏洞环境测试代码修改自 Vulhub 中的 CVE-2016-4437。首先是 Shiro 的配置文件,代码如下所示
@Configuration
public class ShiroConfig {
@Bean
MainRealm mainRealm() {
return new MainRealm();
}
@Bean
RememberMeManager cookieRememberMeManager() {
return (RememberMeManager)new CookieRememberMeManager();
}
@Bean
SecurityManager securityManager(MainRealm mainRealm, RememberMeManager cookieRememberMeManager) {
DefaultWebSecurityManager manager = new DefaultWebSecurityManager();
manager.setRealm((Realm)mainRealm);
manager.setRememberMeManager(cookieRememberMeManager);
return (SecurityManager)manager;
}
@Bean(name = {"shiroFilter"})
ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
bean.setSecurityManager(securityManager);
//设置登录页面uri
bean.setLoginUrl("/login");
//设置登录失败页面uri
bean.setUnauthorizedUrl("/unauth");
Map<String, String> map = new LinkedHashMap<>();
map.put("/doLogin", "anon");
map.put("/doLogout", "authc");
map.put("/user/add","perms[user:add]");
map.put("/user/update","perms[user:update]");
map.put("/user/delete","perms[user:delete]");
map.put("/user/select","perms[user:select]");
map.put("/**", "authc");
bean.setFilterChainDefinitionMap(map);
return bean;
}
}
小伙伴们有兴趣想了解更多相关学习资料请点赞收藏+评论转发+关注我之后私信我,注意回复【000】即可获取更多免费资料!
然后是 Controller 的代码
@Controller
public class UserController {
@PostMapping({"/doLogin"})
public String doLoginPage(@RequestParam("username") String username, @RequestParam("password") String password, @RequestParam(name = "rememberme", defaultValue = "") String rememberMe) {
Subject subject = SecurityUtils.getSubject();
try {
subject.login(new UsernamePasswordToken(username, password, rememberMe.equals("remember-me")));
} catch (AuthenticationException e) {
return "forward:/login";
}
return "forward:/";
}
@RequestMapping({"/doLogout"})
public String doLogout() {
Subject subject = SecurityUtils.getSubject();
subject.logout();
return "forward:/login";
}
@RequestMapping({"/"})
public String helloPage() {
return "hello";
}
@RequestMapping({"/unauth"})
public String errorPage() {
return "error";
}
@RequestMapping({"/login"})
public String loginPage() {
return "loginUser";
}
@RequestMapping({"/user/add"})
public String add(){
return "/user/add";
};
@RequestMapping({"/user/delete"})
public String delete(){
return "/user/delete";
};
@RequestMapping({"/user/update"})
public String update(){
return "/user/update";
};
@RequestMapping({"/user/select"})
public String select(){
Subject subject = Security