目录
一、Shiro简介
Apache Shiro是一个功能强大且易于使用的Java安全(权限)框架。Shiro可以完成:认证、授权、加密、会话管理、与Web集成、缓存等。借助Shiro可以快速轻松地保护任何应用程序——从最小的移动应用程序到最大的Web和企业应用程序。
二、架构体系与专业术语
Subject:主体,可以看到主体可以是任何可以与应用交互的 “用户”;
SecurityManager:安全管理器,是 Shiro 的心脏;所有具体的交互都通过 SecurityManager 进行控制;它管理着所有 Subject、且负责进行认证和授权、及会话、缓存的管理。
Authenticator:认证器,负责主体登录认证,验证用户是否拥有相应身份,可以自定义实现;需要认证策略(Authentication Strategy),即什么情况下算用户认证通过了;
Authorizer:授权器,用来决定主体是否有权限进行相应的操作,能访问应用中的哪些功能;
Realm:域,Shiro 从 Realm 获取安全数据(如用户、角色、权限),就是说 SecurityManager 要验证用户身份,那么它需要从 Realm 获取相应的用户进行比较以确定用户身份是否合法;也需要从 Realm 得到用户相应的角色 / 权限进行验证用户是否能进行操作;可以把 Realm 看成 DataSource,即安全数据源;
SessionManager:会话管理,即用户登录后就是一次会话,在没有退出之前,它的所有信息都在会话中;会话可以是普通 JavaSE 环境的,也可以是如 Web 环境的;
SessionDAO:DAO 大家都用过,数据访问对象,用于会话的 CRUD,比如我们想把 Session 保存到数据库,那么可以实现自己的 SessionDAO,通过如 JDBC 写到数据库;比如想把 Session 放到 Memcached 中,可以实现自己的 Memcached SessionDAO;另外 SessionDAO 中可以使用 Cache 进行缓存,以提高性能;
CacheManager:缓存控制器,来管理如用户、角色、权限等的缓存的;因为这些数据基本上很少去改变,放到缓存中后可以提高访问的性能
Cryptography:密码模块,可以对数据进行加密,如存储数据库的密码。
三、Shiro与SpringSecurity的对比
SpringSecurity基于Spring开发,项目若使用Spring作为基础,配合SpringSecurity做权限更加方便,而Shiro需要和Spring进行整合开发;
SpringSecurity功能比Shiro更加丰富,例如安全维护方面;
SpringSecurity社区资源相对比Shiro更加丰富;
Shiro的配置和使用比较简单,SpringSecurity上手复杂些;
Shiro依赖性低,不需要任何框架和容器,可以独立运行。SpringSecurity依赖Spring容器;
Shiro不仅仅可以使用Web中,它可以工作在任何应用环境中。在集群会话时Shiro最重要的一个好处或许就是它的会话独立于容器的。
四、Shiro优缺点
优点:
简单易用:代码结构简单,易于理解和使用,能够快速集成到项目中。
轻量级:Shiro是一个轻量级的框架,对外部依赖较少,容易集成与部署,可独立运行。
扩展性:Shiro采用模块化的设计结构,可以方便地扩展和定制。
功能完备:Shiro支持多种认证方式、多种数据源、多种Session管理方式等,可以满足大部分项目的安全需求。
缺点:
社区支持:与Spring Security相比,Shiro的社区相对较小,这可能导致在某些特定问题上获取帮助的难度增加。
与Spring框架的集成:Shiro虽然可以与Spring框架集成,但其原生支持并不如Spring Security那样深入和无缝。
五、spring boot 集成 Shiro
1.pom.xml引入依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.18.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.springboot</groupId>
<artifactId>springboot</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springboot</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- shiro -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.5.3</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2.新建ShiroRealm类
package com.springboot.common.shiro;
import com.springboot.repository.bean.UserBean;
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;
/**
* Description 自定义realm
* 在登录接口使用下面代码进行认证
* Subject subject = SecurityUtils.getSubject();
* UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken("userName", "password");
* subject.login(usernamePasswordToken);
*
* 登录成功后,可使用下面代码获取当前登录用户信息
* Object principal = SecurityUtils.getSubject().getPrincipal();
*/
public class ShiroRealm extends AuthorizingRealm {
/**
* @description 权限认证
* @param principalCollection
* @return AuthorizationInfo
**/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
//获取到doGetAuthenticationInfo方法return第一个参数传递的对象
UserBean userBean = (UserBean) principalCollection.getPrimaryPrincipal();
//此处可以查询数据库获取用户对应的权限 与 角色
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
//根据查询的结果,设置权限 与 角色
// info.addStringPermission("xxx");
// info.addRole("xxx");
return info;
}
/**
* @description 登录认证方法
* @param token
* @return AuthenticationInfo
**/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
UsernamePasswordToken user = (UsernamePasswordToken) token;
String username = user.getUsername();
//此处userBean可以通过username查询数据库获取用户信息
UserBean userBean = new UserBean();
userBean.setUserName("zhangsan");
userBean.setPassword("123456");
if (userBean == null) {
return null;
}
//传递第一个参数,可以在doGetAuthorizationInfo授权方法获取到
return new SimpleAuthenticationInfo(userBean, userBean.getPassword(), "");
}
}
3.新建ShiroConfig配置类
package com.springboot.common.shiro;
import org.apache.shiro.mgt.SecurityManager;
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;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* Description shiro配置类
*/
@Configuration
public class ShiroConfig {
/**
* @description 自定义认证realm
* @return ShiroRealm
**/
@Bean
public ShiroRealm shiroRealm() {
return new ShiroRealm();
}
/**
* @description shiro安全管理器
* @return SecurityManager
**/
@Bean(name = "securityManager")
public SecurityManager securityManager() {
DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
defaultWebSecurityManager.setRealm(shiroRealm());
return defaultWebSecurityManager;
}
/**
* @description siro过滤工程
* @param securityManager
* @return ShiroFilterFactoryBean
**/
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier("securityManager") SecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
/*
* anon 不认证
* authc 登录认证
* perms 资源权限认证
* role 角色权限
**/
// filterChainDefinitionMap.put("/user/**", "perms[user]");
filterChainDefinitionMap.put("/user/**", "authc");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilterFactoryBean;
}
}
4.新建LoginController登录接口
package com.springboot.controller;
import com.springboot.common.utils.ResultVO;
import com.springboot.vo.request.UserReq;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.web.bind.annotation.*;
import java.io.IOException;
/**
* @description 登录控制层
**/
@RestController
public class LoginController {
/**
* @description 登录接口
* @param userReq
* @return ResultVO
**/
@RequestMapping("/login")
public ResultVO login(UserReq userReq) {
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(userReq.getUserName(),userReq.getPassword());
subject.login(usernamePasswordToken);
return ResultVO.success();
}
}
标签:集成,return,springboot,shiro,org,apache,import,Shiro
From: https://blog.csdn.net/a360284634/article/details/139765269