一.shiro简介
1.简介
Apache Shiro是一个强大且易用的Java安全框架,执行身份验证、授权、密码学和会话管理。使用Shiro的易于理解的API,您可以快速、轻松地获得任何应用程序,从最小的移动应用程序到最大的网络和企业应用程序。
Shiro 主要分为两个部分就是认证和授权,在个人感觉来看就是查询数据库做相应的判断而已,Shiro只是一个框架而已,其中的内容需要自己的去构建,前后是自己的,中间是Shiro帮我们去搭建和配置好的。
2.涉及到的名词
Subject
即主体,外部应用与subject进行交互,subject记录了当前操作用户,将用户的概念理解为当前操作的主体,可能是一个通过浏览器请求的用户,也可能是一个运行的程序。 Subject在shiro中是一个接口,接口中定义了很多认证授相关的方法,外部程序通过subject进行认证授,而subject是通过SecurityManager安全管理器进行认证授权
SecurityManager
安全管理器,对全部的subject进行安全管理,它是shiro的核心,负责对所有的subject进行安全管理。
Authenticator
即认证器,对用户身份进行认证,Authenticator是一个接口,shiro提供ModularRealmAuthenticator实现类,通过ModularRealmAuthenticator基本上可以满足大多数需求,也可以自定义认证器。
Authorizer
即授权器,用户通过认证器认证通过,在访问功能时需要通过授权器判断用户是否有此功能的操作权限。
realm
即领域,相当于datasource数据源,securityManager进行安全认证需要通过Realm获取用户权限数据。
二.与spring boot整合
1.pom.xml添加依赖
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.3.2</version>
</dependency>
2.编写UserRealm类
//UserRealm.java
import com.yang.utils.ShiroUtils;
import com.yang.domain.UserDO;
import com.yang.service.RoleService;
import com.yang.service.UserService;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class UserRealm extends AuthorizingRealm {
@Autowired
UserDao userMapper;
@Autowired
RoleService roleService;
//编写授权代码
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {
String userId = ShiroUtils.getUserId();
Set<String> perms = roleService.listPerms(userId);
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
info.setStringPermissions(perms);
System.out.println("");
return info;
}
//编写认证代码
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
String username = (String) token.getPrincipal();
Map<String, Object> map = new HashMap<>(16);
map.put("username", username);
String password = new String((char[]) token.getCredentials());
// 查询用户信息
UserDO user = userService.list(map).get(0);
// 账号不存在
if (user == null) {
throw new UnknownAccountException("账号或密码不正确");
}
// 密码错误
if (!password.equals(user.getPassword())) {
throw new IncorrectCredentialsException("账号或密码不正确");
}
// 账号锁定
if (user.getStatus().equals("0")) {
throw new LockedAccountException("账号已被锁定,请联系管理员");
}
SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, password, getName());
return info;
}
}
3.编写controller类
//用户登录
@PostMapping("/login")
@ResponseBody
public String ajaxLogin(String username, String password) {
password = MD5Utils.encrypt(username, password);
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
Subject subject = SecurityUtils.getSubject();
try {
subject.login(token);
return "登录成功";
} catch (AuthenticationException e) {
return "用户或密码错误";
}
}
//注销
@GetMapping("/logout")
String logout() {
SecurityUtils.getSubject.logout();
return "redirect:/login";
}