环境搭建
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.4.1</version>
</dependency>
Spring-Shiro整合依赖文本
再加入一些springboot web项目常用依赖
几个简单页面跳转
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>登录</h1>
<p th:text="${msg}" style="color: red"></p>
<form th:action="@{/login}">
<p>用户名:<input type="text" name="username"></p>
<p>密码:<input type="text" name="password"></p>
<p> <input type="submit"></p>
</form>
</body>
</html>
给springboot以注入bean的方式进行设置
配置shiro需要三个配置
/*ShiroFilterFactoryBean*/
/*DefaultWebSecurityManager*/
/*创建Realm对象,需要自定义类*/
@Configuration
public class ShiroConfig {
/*ShiroFilterFactoryBean*/
@Bean
public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager defaultWebSecurityManager){
ShiroFilterFactoryBean bean =new ShiroFilterFactoryBean();
/*设置安全管理器*/
bean.setSecurityManager(defaultWebSecurityManager);
/*添加shiro的内置过滤器
* anon 无需认证就能访问
* authc 必须认证了才能访问
* user 必须拥有记住我才能访问
* perms 拥有对某个资源的权限才能访问
* role 拥有某个角色权限才能访问
* */
Map<String, String> filterMap = new LinkedHashMap<>();
filterMap.put("/user/add","anon");
filterMap.put("/user/update","authc");
bean.setFilterChainDefinitionMap(filterMap);
return bean;
}
/*DefaultWebSecurityManager*/
@Bean(name = "securityManager")
public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm")UserRealm userRealm){
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
/*关联realm*/
securityManager.setRealm(userRealm);
return securityManager;
}
/*创建Realm对象,需要自定义类*/
@Bean
public UserRealm userRealm(){
return new UserRealm();
}
}
UserRealm需要自己定义
/*继承授权*/
public class UserRealm extends AuthorizingRealm {
/*授权*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
System.out.println("执行了授权Authorization");
return null;
}
/*认证*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
System.out.println("执行了认证Authentication");
return null;
}
}
/*添加shiro的内置过滤器
* anon 无需认证就能访问
* authc 必须认证了才能访问
* user 必须拥有记住我才能访问
* perms 拥有对某个资源的权限才能访问
* role 拥有某个角色权限才能访问
* */
Map<String, String> filterMap = new LinkedHashMap<>();
filterMap.put("/user/add","anon");
filterMap.put("/user/update","authc");
bean.setFilterChainDefinitionMap(filterMap);
设置过滤链定义Map
找个方法在源码中需要一个map
对我们的请求进行设置
add请求为anon,不用认证就能访问
update为authc 必须认证才能访问
shiro是一个轻量化的安全框架,所以和springSecurity不一样,没有自带的登录页面,所以要自己写登录页面
登录界面认证
流程:
-
设置登录请求
-
处理登录数据时封装成token
-
与后台数据进行认证
-
设置登录请求
-
bean.setLoginUrl("/tologin");
-
前端表单提交数据
-
<h1>登录</h1> <p th:text="${msg}" style="color: red"></p> <form th:action="@{/login}"> <p>用户名:<input type="text" name="username"></p> <p>密码:<input type="text" name="password"></p> <p> <input type="submit"></p> </form>
-
设置RequestMapping请求
-
@RequestMapping("/login") public String login(String username, String password, Model model) { /*获取当前的用户*/ Subject subject= SecurityUtils.getSubject(); /*封装用户的登录数据,制作成一个token令牌加密*/ UsernamePasswordToken token = new UsernamePasswordToken(username,password); /*获取令牌后可以设置记住我*/ try { /*执行登录的方法,如有有异常需要捕获*/ subject.login(token); return "index"; } catch (UnknownAccountException e) {/*用户名不存在*/ model.addAttribute("msg","用户名错误"); return "login"; } catch (IncorrectCredentialsException e){/*密码不存在*/ model.addAttribute("msg","密码错误"); return "login"; } }
-
提交登录后会执行UserRealm的doGetAuthenticationInfo认证请求
-
/*认证*/ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { System.out.println("执行了认证Authentication"); /*用户名和密码在数据库中获取*/ String name = "root"; String password ="123"; UsernamePasswordToken userToken = (UsernamePasswordToken) authenticationToken; if(!userToken.getUsername().equals(name)){ /*会抛出异常,UnknownAccountException */ return null; } return new SimpleAuthenticationInfo("",password,""); }
-
这些数据应该从数据库中读取,所以要和mybatis整合一下
-
url方面还要改进一下
-
默认了remember-me
-
时常14天