Spring Boot Shiro在Web应用中的作用详解
简介
Spring Boot Shiro是基于Spring Boot和Shiro的安全管理框架,可以方便地集成到Web应用中。它提供了一种简单、灵活且强大的身份验证和授权机制,可以在应用中实现多种安全需求,并且易于扩展和定制。
快速开始
依赖
在您的pom.xml文件中添加Spring Boot Shiro的依赖:
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring-boot-web-starter</artifactId>
<version>1.7.1</version>
</dependency>
配置
在application.yml中添加shiro相关的配置:
# shiro
shiro:
# 登录url
loginUrl: /login
# 成功后跳转的url
successUrl: /index
# 未授权url
unauthorizedUrl: /403
# 登出url
logoutUrl: /logout
# shiro加密方式
hashAlgorithmName: md5
# hash次数
hashIterations: 1024
# 是否开启记住我
rememberMe: true
cookie:
# cookie名称
name: rememberMe
# cookie过期时间
maxAge: 604800
# cookie加密密钥
cipherKey: 8AvVhmFLUs0KTA3Kprsdag==
# Shiro 配置
shiro:
# ShiroFilter 配置
filter:
# 设置默认过滤器,顺序有讲究,细节请看文档,登陆成功主要看user这个拦截器
loginUrl: /login
unauthorizedUrl: /403
anon: anon
user: user
logout: logout
# ShiroRealm 配置
realm:
# 自定义的Realm类
class-name: com.test.realm.UserRealm
# 加密方式
credentialsMatcher:
hashAlgorithmName: MD5
hashIterations: 1024
实现UserRealm
自定义UserRealm需要继承Shiro的AuthorizingRealm类,并实现doGetAuthorizationInfo()和doGetAuthenticationInfo()方法。其中,doGetAuthorizationInfo()用于获取授权信息,doGetAuthenticationInfo()用于获取身份验证信息。
以下是一个示例:
public class UserRealm extends AuthorizingRealm {
@Autowired
private UserService userService;
// 获取授权信息
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
//获取登录用户名
String username= (String) principalCollection.getPrimaryPrincipal();
// 根据用户名查询该用户的角色和权限
User user = userService.findByUserName(username);
Set<String> roles = new HashSet<>();
roles.add(user.getRole());
authorizationInfo.setRoles(roles);
Set<String> permissions = new HashSet<>();
permissions.add(user.getPermissions());
authorizationInfo.setStringPermissions(permissions);
return authorizationInfo;
}
// 获取身份验证信息
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
UsernamePasswordToken token = (UsernamePasswordToken)authenticationToken;
String username = token.getUsername();
User user = userService.findByUserName(username);
if(user == null){
throw new UnknownAccountException("用户名或密码错误!");
}
return new SimpleAuthenticationInfo(username,user.getPassword(),getName());
}
}
实现登录、登出、授权
在controller中添加对应的方法来实现登录、授权、登出等功能。以下是一个示例:
@RestController
public class UserController {
// 用户登录
@PostMapping("/login")
public Result login(@RequestParam String username,
@RequestParam String password,
@RequestParam(defaultValue = "false") Boolean rememberMe){
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken(username,password,rememberMe);
try{
subject.login(token);
User user = (User)subject.getPrincipal();
return Result.success("登录成功!", user);
}catch (UnknownAccountException e){
throw new UnknownAccountException("用户名或密码错误!");
}catch (IncorrectCredentialsException e){
return Result.error("用户名或密码错误!");
}
}
// 用户登出
@RequestMapping("/logout")
public String logout(){
Subject subject = SecurityUtils.getSubject();
subject.logout();
return "redirect:/login";
}
// 用户授权
@GetMapping("/index")
@RequiresPermissions("user:index")
public String index(){
return "index";
}
}
示例
示例一:基于注解的权限控制
@RestController
public class UserController {
// 用户首页
@GetMapping("/index")
@RequiresPermissions("user:index")
public String index(){
return "This is index page.";
}
// 用户列表
@GetMapping("/user/list")
@RequiresPermissions("user:list")
public String list(){
return "This is user list page.";
}
// 用户编辑
@GetMapping("/user/edit")
@RequiresPermissions("user:edit")
public String edit(){
return "This is user edit page.";
}
// 用户删除
@GetMapping("/user/delete")
@RequiresPermissions("user:delete")
public String delete(){
return "This is user delete page.";
}
}
该示例中,使用@RequiresPermissions注解定义访问该方法需要的权限。当用户没有该权限时,访问该方法会返回403错误页面。
示例二:记住我功能和退出登录
@RestController
public class UserController {
// 用户列表
@GetMapping("/user/list")
@RequiresPermissions("user:list")
public String list(){
return "This is user list page.";
}
// 用户首页
@GetMapping("/index")
@RequiresPermissions("user:index")
public String index(){
return "This is index page.";
}
// 用户登录
@RequestMapping(value = "/login", method = RequestMethod.POST)
public String login(@RequestParam String username,
@RequestParam String password,
@RequestParam(defaultValue = "false") Boolean rememberMe,
HttpServletRequest request){
Subject currentUser = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
token.setRememberMe(rememberMe);
try{
currentUser.login(token);
User user = (User) currentUser.getPrincipal();
request.getSession().setAttribute("user", user);
return "redirect:/index";
} catch (UnknownAccountException uae) {
return "用户名不存在";
} catch (IncorrectCredentialsException ice) {
return "密码不正确";
}
}
// 退出登录
@RequestMapping(value = "/logout", method = RequestMethod.GET)
public String logout(HttpServletRequest request){
SecurityUtils.getSubject().logout(); //完成退出
request.getSession().invalidate();
return "redirect:/login";
}
}
该示例中,使用HttpServletRequest来获取Session,并将登录用户信息保存到Session中,以便实现记住我功能。同时,当用户点击退出登录时,使用SecurityUtils.getSubject().logout()方法来完成退出操作,并清除Session。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Spring Boot Shiro在Web应用中的作用详解 - Python技术站