Shiro 实践记录-爱代码爱编程
1.Shiro
什么是Shiro
Shiro是一款主流的Java安全框架,不依赖任何容器,可以运行在Java SE和Java EE项目中
,它的主要作用是对访问系统的用户进行身份认证、授权、会话管理、加密登操作。
2.Shiro核心组件
用户、角色、权限
会给角色赋予权限,给用户赋予角色。
运行机制流程图
3.SpringBoot 集成Shiro
Maven
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.5.3</version>
</dependency>
Realm实现
继承AuthorizingRealm
import com.suiyaner.entity.User;
import com.suiyaner.service.UserService;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
public class UserRealm extends AuthorizingRealm {
@Autowired
private UserService userService;
/**
* 授权
* @param principalCollection
* @return
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
return null;
}
/**
* 认证
* @param authenticationToken
* @return
* @throws AuthenticationException
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
//客户端传送过来的用户名密码
UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) authenticationToken;
//根据Token中的用户名在数据库中查找
User user = userService.findUserByName(usernamePasswordToken.getUsername());
if (user != null) {
//验证密码
return new SimpleAuthenticationInfo(user,user.getPassword(),getName());
}
return null;
}
}
Config配置类配置
Qualifier 寻找方法类
import com.suiyaner.realm.UserRealm;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class ShiroConfig {
@Bean
public UserRealm userRealm(){
return new UserRealm();
}
@Bean
public DefaultWebSecurityManager defaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){
DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
defaultWebSecurityManager.setRealm(userRealm);
return defaultWebSecurityManager;
}
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier("defaultWebSecurityManager") DefaultWebSecurityManager defaultWebSecurityManager){
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);
//权限设置
Map<String,String> map = new Hashtable<>();
map.put("/main","authuc"); // 必须登录状态
map.put("/manager","perms[manager]"); //必须拥有manager权限
map.put("/administrator","roles[administrator]"); //必须是administrator角色
shiroFilterFactoryBean.setFilterChainDefinitionMap(map); //把map添加进shiroFilterFactoryBean
//修改登录页面
shiroFilterFactoryBean.setLoginUrl("/login");
//设置未授权页面
shiroFilterFactoryBean.setUnauthorizedUrl("/unauth");
return shiroFilterFactoryBean;
}
}
编写认证和授权规则:
认证过滤器
anon:无需认证。
authc:必须认证。
authcBasic:需要通过 HTTPBasic 认证。
user:不一定通过认证,只要曾经被 Shiro 记录即可,比如:记住我。
授权过滤器
perms:必须拥有某个权限才能访问。
role:必须拥有某个角色才能访问。
port:请求的端口必须是指定值才可以。
rest:请求必须基于 RESTful,POST、PUT、GET、DELETE。
ssl:必须是安全的 URL 请求,协议 HTTPS。
创建 3 个页面,main.html、manage.html、administrator.html
访问权限如下:
1、必须登录才能访问 main.html
2、当前用户必须拥有 manage 授权才能访问 manage.html
3、当前用户必须拥有 administrator 角色才能访问 administrator.html
Login实现
@PostMapping("/login")
public String login(String username, String password, Model model){
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken(username,password);
try {
subject.login(token);
User user = (User) subject.getPrincipal();
subject.getSession().setAttribute("user",user);
return "index";
} catch (UnknownAccountException e) {
e.printStackTrace();
model.addAttribute("msg","用户名错误!");
return "login";
} catch (IncorrectCredentialsException e){
model.addAttribute("msg","密码错误!");
e.printStackTrace();
return "login";
}
}
@GetMapping("/unauth")
@ResponseBody
public String unauth(){
return "未授权,无法访问!";
}
@GetMapping("/logout")
public String logout(){
Subject subject = SecurityUtils.getSubject();
subject.logout();
return "login";
}
Shiro 整合 Thymeleaf
1、pom.xml 引入依赖
<dependency>
<groupId>com.github.theborakompanioni</groupId>
<artifactId>thymeleaf-extras-shiro</artifactId>
<version>2.0.0</version>
</dependency>
2、配置类添加 ShiroDialect
@Bean
public ShiroDialect shiroDialect(){
return new ShiroDialect();
}
3、index.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.thymeleaf.org/thymeleaf-extras-shiro">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="shortcut icon" href="#"/>
</head>
<body>
<h1>index</h1>
<div th:if="${session.account != null}">
<span th:text="${session.account.username}+'欢迎回来!'"></span><a href="/logout">退出</a>
</div>
<a href="/main">main</a> <br/>
<div shiro:hasPermission="manage">
<a href="manage">manage</a> <br/>
</div>
<div shiro:hasRole="administrator">
<a href="/administrator">administrator</a>
</div>
</body>
</html>
div>
<a href="/main">main</a> <br/>
<div shiro:hasPermission="manage">
<a href="manage">manage</a> <br/>
</div>
<div shiro:hasRole="administrator">
<a href="/administrator">administrator</a>
</div>
</body>
</html>
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 本文链接: https://blog.csdn.net/qq_27305257/article/details/111070686