上海建设官方网站,360企业自助建站,公司品牌网络推广方案,做文字头像的网站1. Shiro简介
Shiro是一个强大且灵活的Java安全框架#xff0c;专注于认证、授权、加密、会话管理等功能#xff0c;能够无缝集成到现有的应用程序中。相比Spring Security#xff0c;Shiro的学习曲线较为平缓#xff0c;配置简单
(1) Shiro特性
认证#xff08;Authen…1. Shiro简介
Shiro是一个强大且灵活的Java安全框架专注于认证、授权、加密、会话管理等功能能够无缝集成到现有的应用程序中。相比Spring SecurityShiro的学习曲线较为平缓配置简单
(1) Shiro特性
认证Authentication身份验证确认用户的身份信息授权Authorization基于角色或权限控制访问资源会话管理Session Management支持JavaSE和JavaEE环境下的会话管理加密Cryptography提供用于安全操作的加密API易扩展性Shiro的各个模块是解耦的开发者可以根据需要进行灵活扩展
(2) Shiro架构
Shiro的核心架构主要由以下几部分组成
Subject表示当前用户包括已登录和未登录的用户SecurityManagerShiro的核心控制器管理所有安全操作相当于Spring Security中的Filter ChainRealm用于连接实际数据源如数据库和Shiro负责根据用户凭证获取相应的权限、角色信息
2. 认证Authentication
认证是Shiro中的一个重要部分主要验证用户的身份
(1) Token
Shiro中的认证是基于令牌Token的最常用的令牌是UsernamePasswordToken它包含用户名和密码用于在登录时进行身份验证
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//package org.apache.shiro.authc;public class UsernamePasswordToken implements HostAuthenticationToken, RememberMeAuthenticationToken {private String username;private char[] password;private boolean rememberMe;private String host;public UsernamePasswordToken() {this.rememberMe false;}public UsernamePasswordToken(String username, char[] password) {this(username, (char[])password, false, (String)null);}public UsernamePasswordToken(String username, String password) {this(username, (char[])(password ! null ? password.toCharArray() : null), false, (String)null);}public UsernamePasswordToken(String username, char[] password, String host) {this(username, password, false, host);}public UsernamePasswordToken(String username, String password, String host) {this(username, password ! null ? password.toCharArray() : null, false, host);}public UsernamePasswordToken(String username, char[] password, boolean rememberMe) {this(username, (char[])password, rememberMe, (String)null);}public UsernamePasswordToken(String username, String password, boolean rememberMe) {this(username, (char[])(password ! null ? password.toCharArray() : null), rememberMe, (String)null);}public UsernamePasswordToken(String username, char[] password, boolean rememberMe, String host) {this.rememberMe false;this.username username;this.password password;this.rememberMe rememberMe;this.host host;}public UsernamePasswordToken(String username, String password, boolean rememberMe, String host) {this(username, password ! null ? password.toCharArray() : null, rememberMe, host);}public String getUsername() {return this.username;}public void setUsername(String username) {this.username username;}public char[] getPassword() {return this.password;}public void setPassword(char[] password) {this.password password;}public Object getPrincipal() {return this.getUsername();}public Object getCredentials() {return this.getPassword();}public String getHost() {return this.host;}public void setHost(String host) {this.host host;}public boolean isRememberMe() {return this.rememberMe;}public void setRememberMe(boolean rememberMe) {this.rememberMe rememberMe;}public void clear() {this.username null;this.host null;this.rememberMe false;if (this.password ! null) {for(int i 0; i this.password.length; i) {this.password[i] 0;}this.password null;}}public String toString() {StringBuilder sb new StringBuilder();sb.append(this.getClass().getName());sb.append( - );sb.append(this.username);sb.append(, rememberMe).append(this.rememberMe);if (this.host ! null) {sb.append( ().append(this.host).append());}return sb.toString();}
}(2) 认证流程
Shiro的认证流程如下
用户提交身份认证请求通常为登录操作Shiro将用户信息封装为TokenSubject.login(token)方法调用将Token传递给SecurityManagerSecurityManager通过Realm查找用户信息并验证凭证验证通过后Shiro会将用户的信息存储到会话中
(3) 记住我VS认证
认证用户成功登录并创建会话Session管理用户的登录状态记住我用户选择记住我功能后即使关闭浏览器用户信息也能在下次访问时恢复但不一定是完全的会话恢复。Shiro通过Cookie机制实现这一点
(4) 注销Logout
注销操作通过Subject.logout()方法实现。Shiro会自动清除Session并将相关的登录信息从SecurityManager中移除
SecurityUtils.getSubject().logout();//shiro再注销一下
3. SpringBootShiro认证
在SpringBoot项目中集成Shiro非常简单只需进行少量配置即可实现认证功能
(1) 导入Shiro相关依赖
dependencygroupIdorg.apache.shiro/groupIdartifactIdshiro-spring/artifactIdversion1.8.0/version
/dependency(2) 自定义Realm
自定义Realm用于连接数据库进行身份认证和授权
package com.ktjiaoyu.crm.config.shiro;import com.ktjiaoyu.crm.pojo.User;
import com.ktjiaoyu.crm.service.UserService;
import jakarta.annotation.Resource;
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;/*** Author: wangtao* CreateTime: 2024-10-16-19:07* Description: 自定义Realm* Version: 1.0*/public class MyShiroRealm extends AuthorizingRealm {Resourceprivate UserService userService;Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {System.out.println(调用MyShiroRealm.doGetAuthorizationInfo获取权限信息);//获取权限信息User user (User) principalCollection.getPrimaryPrincipal();SimpleAuthorizationInfo info new SimpleAuthorizationInfo();//暂不授予权限信息下章再搞授权return info;}Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {System.out.println(调用MyShiroRealm.doGetAuthorizationInfo获取身份信息);//获取身份信息UsernamePasswordToken token (UsernamePasswordToken) authenticationToken;String usrName token.getUsername();User user userService.getUserByUsrName(usrName);if(user null){throw new UnknownAccountException();//账号错误}if(user.getUsrFlag() null || user.getUsrFlag().intValue() 0){throw new LockedAccountException();//账号锁定}SimpleAuthenticationInfo info new SimpleAuthenticationInfo(user, user.getUsrPassword(), getName());//返回身份信息return info;}
}(3) 配置Shiro相关对象
在SpringBoot中配置Shiro包含SecurityManager、过滤器和自定义Realm
package com.ktjiaoyu.crm.config.shiro;import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.util.ThreadContext;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/*** Author: wangtao* CreateTime: 2024-10-16-19:15* Description: Shiro配置类* Version: 1.0*/Configuration
public class ShiroConfig {Beanpublic MyShiroRealm myShiroRealm(){//自定义RealmMyShiroRealm myShiroRealm new MyShiroRealm();return myShiroRealm;}Beanpublic SecurityManager securityManager(){//安全管理器DefaultWebSecurityManager securityManager new DefaultWebSecurityManager();ThreadContext.bind(securityManager);//加上这句代码手动绑定//注入RealmsecurityManager.setRealm(myShiroRealm());return securityManager;}Beanpublic ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager){//shiro过滤器权限认证ShiroFilterFactoryBean shiroFilterFactoryBean new ShiroFilterFactoryBean();//注入securityManagershiroFilterFactoryBean.setSecurityManager(securityManager);//权限验证使用Filter控制资源URL的访问return shiroFilterFactoryBean;}
}(4) 测试认证登录
配置好之后可以通过以下方式测试登录功能
//创建Realm安全数据源
IniRealm realm new IniRealm(classpath:shiro.ini);
//通过shiro.ini配置文件 创建Realm
DefaultSecurityManager securityManager new DefaultSecurityManager(realm);//注入创建的Realm安全数据源
securityManager.setRealm(realm);
SecurityUtils.setSecurityManager(securityManager);
//进行认证
Subject subject SecurityUtils.getSubject();
//封装令牌
UsernamePasswordToken token new UsernamePasswordToken(admin, 123456);
try {
subject.login(token);
}catch (AuthenticationException e){
e.printStackTrace();
}
System.out.println(是否认证通过subject.isAuthenticated());
System.out.println(身份信息subject.getPrincipal());