shiro
在springboot中集成shiro也是非常容易的,其步骤不过是添加了几个依赖,然后配置下基本参数即可进行使用
- 创建好springboot项目,引入shiro的starter依赖
<!--其他的自己随意添加吧,就平时开发web用到的东西-->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring-boot-web-starter</artifactId>
<version>1.9.0</version>
</dependency>
- 自定义Realm
自定义Realm需要继承AuthorizingRealm类,需要实现两个方法,分别是doGetAuthorizationInfo,它是自定义的授权方法,以及doGetAuthenticationInfo,它是自定义的登录认证方法,下面简单实现一下,
- 不要关注我的代码写了什么,而是去看注释,看看和shiro的基础使用有什么区别,以及它的认证逻辑是怎样的
/**
* @author GYL
* @version V1.0
*/
@Component
public class MyRealm extends AuthorizingRealm {
@Autowired
private UserService userService;
/**
* 自定义授权方法--暂时不做实现
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
System.out.println("进入自定义授权方法");
return null;
}
/**
* 自定义登录认证方法
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
// 获取用户身份信息
String name = authenticationToken.getPrincipal().toString();
// 获取数据中用户信息(数据库)
User user = userService.getUserInfo(name);
// 判断有信息,将数据进行封装后返回
if (user != null) {
return new SimpleAuthenticationInfo(
authenticationToken.getPrincipal(),
user.getPassword(),
ByteSource.Util.bytes("salt"),
name
);
}
return null;
}
}
- 定义shiroConfig
/**
* @author GYL
* @version V1.0
*/
@Configuration
public class ShiroConfig {
@Autowired
private MyRealm myRealm;
/**
* 配置shiro的SecurityManager
*/
@Bean
public DefaultWebSecurityManager defaultWebSecurityManager() {
// 创建对象
DefaultWebSecurityManager manager = new DefaultWebSecurityManager();
// 创建加密对象,设置相关属性
HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();
// 采用md5加密
matcher.setHashAlgorithmName("MD5");
// 迭代加密次数为3
matcher.setHashIterations(3);
// 将加密对象存储到myRealm中
myRealm.setCredentialsMatcher(matcher);
// 将myRealm存入manager对象
manager.setRealm(myRealm);
// 返回对象
return manager;
}
/**
* 配置shiro内置拦截器的拦截范围
*/
@Bean
public DefaultShiroFilterChainDefinition shiroFilterChainDefinition() {
DefaultShiroFilterChainDefinition chainDefinition = new DefaultShiroFilterChainDefinition();
// 设置不认证可以访问的资源 -- DefaultFilter.class
/*
anon : 允许匿名访问,无需登录
authc : 需要经过认证的用户才可以访问
logout :执行退出操作,执行后重定向到loginUrl页面(在application.yml中配置)
roles :拥有指定权限的用户可以访问
*/
chainDefinition.addPathDefinition("/api/userLogin", "anon");
chainDefinition.addPathDefinition("/api/login", "anon");
// 设置需要登录认证的拦截范围
chainDefinition.addPathDefinition("/**", "authc");
return chainDefinition;
}
}
此时其实已经基础整合完毕了,如果需要效果,那就来继续吧
- 定义接口
/**
* 跳转登录页面
*/
@GetMapping("login")
public String login() {
return "login";
}
/**
* 登录接口
*/
@GetMapping("/userLogin")
public String userLogin(String name,
String password,
HttpSession session) {
// 获取subject对象
Subject subject = SecurityUtils.getSubject();
// 封装请求数据到token
AuthenticationToken token = new UsernamePasswordToken(name, password);
// 调用login方法进行登录认证
try {
subject.login(token);
session.setAttribute("user", token.getPrincipal().toString());
return "main";
} catch (AuthenticationException e) {
e.printStackTrace();
System.out.println("登录失败");
return "登录失败";
}
}
shiro:
loginUrl: /api/login
- 创建页面
– login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>shiro登录认证</h1>
<br>
<form action="/api/userLogin">
<div>用户名:<input type="text" name="name"></div>
<div>密码:<input type="password" name="password"></div>
<div>记住用户:
<input type="checkbox" name="rememberMe" value="true">
</div>
<div><input type="submit" value="登录"></div>
</form>
</body>
</html>
– main.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>Shiro 登录认证后主页面</h1>
<br>
登录用户为:<span th:text="${session.user}"></span>
</body>
- 测试
打开浏览器访问该main页面,试试不登录到底是否可以登录成功,再访问login页面,输入数据库中信息或者自己的模拟信息,点击登录即可登录成功
做到这里其实应该会比较熟悉了,这不就是我们平常做的登录认证吗,其实就是,shiro底层的执行流程大概就是一串过滤器,如果感兴趣的话,可以参考官方文档。
- 如果哪里还有不清楚的,可以看shiro官网,哪里有问题,请不要吝啬您的批评