当前位置: 首页 > news >正文

Shiro认证

Apache Shiro 是一个强大而灵活的 Java 安全框架,主要用于处理身份认证、授权、加密和会话管理等。以下是关于 Apache Shiro 的详细介绍:

一、主要功能

  1. 身份认证

    • 确定用户的身份。可以验证用户提供的凭证(如用户名和密码)与存储在系统中的信息是否匹配。
    • 支持多种认证方式,如用户名 / 密码、数字证书、LDAP 等。
  2. 授权

    • 控制用户对系统资源的访问权限。可以根据用户的角色、权限等信息来决定用户是否能够访问特定的功能或资源。
    • 提供了灵活的授权策略,可以基于角色、权限、资源等进行授权。
  3. 加密

    • 对敏感数据进行加密,保护数据的安全性。
    • 支持多种加密算法,如 AES、DES 等。
  4. 会话管理

    • 管理用户的会话状态,包括登录状态、超时处理等。
    • 提供了会话的创建、销毁、验证等功能。

    5.等等。。。。。。

二, 快速上手:

添加依赖

        <dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-spring</artifactId><version>1.4.1</version></dependency>

配置shiro.ini文件

#对用户信息进行配置
[users]
#用户账号密码
#配置规则:用户账号=密码,角色1,角色2
admin=123456,管理员
czkt=111111,客户经理
#对权限信息进行配置,基于角色配置
[roles]
#角色和权限
#配置规则:角色名称=权限1,权限2,权限字符串可使用通配符配置
管理员=user:*,role:*
#客户经理只能对用户进行列表和详细的查看操作
客户经理=user:list,user:view

 认证测试

package com.bdqn.shiro;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.realm.text.IniRealm;
import org.apache.shiro.subject.Subject;
import org.junit.Test;
public class ShiroTest {@Test
public void testShiro(){//1创建Realm(安全数据源)//通过shiro.ini配置文件创建RealmIniRealm realm=new IniRealm("classpath:shiro.ini");//2创建SecurityManagerDefaultSecurityManager securityManager=new DefaultSecurityManager();//注入创建的Realm(安全数据源)securityManager.setRealm(realm);SecurityUtils.setSecurityManager(securityManager);//3,操作Subject,进行认证Subject subject=SecurityUtils.getSubject();//封装一个令牌UsernamePasswordToken token=new UsernamePasswordToken("admin","123456");try {subject.login(token);} catch (AuthenticationException e) {System.out.println("认证异常");e.printStackTrace();}System.out.println("是否认证通过:"+subject.isAuthenticated());//认证通过后,进行权限验证System.out.println("是否为管理员角色"+subject.hasRole("管理员"));//判断是否为某个角色System.out.println("是否能操作用户查看功能"+subject.isPermitted("user:view"));//判断是否拥有某个权限//也可以使用check方法判断是否拥有某权限,但是失败的情况下会抛出UnauthorizedException异常subject.checkPermission("user:view");}
}

 运行结果

18:47:48.757 [main] INFO org.apache.shiro.session.mgt.AbstractValidatingSessionManager -- Enabling session validation scheduler...
是否认证通过:true
是否为管理员角色true
是否能操作用户查看功能true

 SpringBoot+Shiro认证:

 可以自定义一个Realm,需要继承AuthorizingRealm类,这个类封装了很多方法,并继承自Realm类,我们需要重写下面2个方法:

doGetAuthenticationInfo()方法:获取身份信息

doGetAuthorizationInfo()方法:获取权限信息

package com.bdqn.config;
import com.bdqn.pojo.Right;
import com.bdqn.pojo.Role;
import com.bdqn.pojo.User;
import com.bdqn.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;
import java.util.Set;
public class MyShiroRealm extends AuthorizingRealm {//安全数据源@Resourceprivate UserService userService;@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {System.out.println("调用MyShiroRealm的doGetAuthenticationInfo获取身份信息");//获得身份信息UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;String usrName = token.getUsername();User user = userService.getUserByUsrName(usrName);if (user == null) {throw new AuthenticationException();//账号错误}if (user.getUsrFlag() == null || user.getUsrFlag().intValue() == 0) {throw new LockedAccountException();//账号被禁用}SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user,user.getUsrPassword(),getName());//返回身份信息return info;}@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {System.out.println("调用 MyShiroRealm 的 doGetAuthorizationInfo 获取权限信息");// 获得权限信息User user = (User) principalCollection.getPrimaryPrincipal();SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
//        // 静态授权:授予主体(用户)相应的角色和权限
//        info.addRole("用户列表");
//        if ("管理器".equals(user.getRole().getRoleName())) { // 管理员拥有"增删改"权限
//            info.addStringPermission("用户添加");
//            info.addStringPermission("用户编辑");
//            info.addStringPermission("用户删除");
//        }
//        System.out.println("为用户 " + user.getUsrName() + " 分配的权限:" + info.getStringPermissions());
//        return info;//动态授权Role role = user.getRole();if (role != null) {info.addRole(role.getRoleName());Set<Right> rights = role.getRights();if (rights != null && rights.size() > 0) {for (Right right : rights) {info.addStringPermission(right.getRightCode());}}}return info;}
}

 配置Shiro相关对象:

package com.bdqn.config;
import com.bdqn.pojo.Right;
import com.bdqn.service.RoleService;
import jakarta.annotation.Resource;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@Configuration
public class ShiroConfig {@Resourceprivate RoleService roleService;/*** 开启Shiro注解* @returnk*/@Beanpublic DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator(){DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();advisorAutoProxyCreator.setProxyTargetClass(true);return advisorAutoProxyCreator;}/*** 开启aop注解支持* @return*/@Beanpublic AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);return authorizationAttributeSourceAdvisor;}@Beanpublic MyShiroRealm myShiroRealm() {// 自定义RealmMyShiroRealm myShiroRealm = new MyShiroRealm();return myShiroRealm;}@Beanpublic SecurityManager securityManager(){// 安全管理器SecurityManagerDefaultSecurityManager securityManager=new DefaultSecurityManager();// 注入RealmsecurityManager.setRealm(myShiroRealm());SecurityUtils.setSecurityManager(securityManager);return securityManager;}@Beanpublic ShiroFilterFactoryBean shiroFilterFactory(SecurityManager securityManager){ShiroFilterFactoryBean shiroFilterFactory=new ShiroFilterFactoryBean();// 注入SecurityManagershiroFilterFactory.setSecurityManager(securityManager);// 权限验证:使用Filter控制资源(URL)的访问shiroFilterFactory.setLoginUrl("/login");shiroFilterFactory.setSuccessUrl("/main");shiroFilterFactory.setUnauthorizedUrl("/403");//没有权限跳转403页面Map<String,String> filterChainDefinitionMap=new LinkedHashMap<String,String>();//必须使用LinkHashMap(有序集合)// 配置可以匿名访问的资源(URL):静态资源filterChainDefinitionMap.put("/css/**","anon");filterChainDefinitionMap.put("/fonts/**","anon");filterChainDefinitionMap.put("/images/**","anon");filterChainDefinitionMap.put("/js/**","anon");filterChainDefinitionMap.put("/localcss/**","anon");filterChainDefinitionMap.put("/localjs/**","anon");filterChainDefinitionMap.put("/login","anon");filterChainDefinitionMap.put("/logout","logout");//配置需要特定权限才能访问的资源(URL)//静态授权:包括全部需要特定权限才能访问的资源(URL)filterChainDefinitionMap.put("/user/list","perms[用户列表]");filterChainDefinitionMap.put("/user/add","perms[用户添加]");
//        filterChainDefinitionMap.put("/user/edit","perms[用户编辑]");filterChainDefinitionMap.put("/user/del","perms[用户删除");//动态授权List<Right> rights=roleService.findAllRights();for(Right right:rights){if(right.getRightUrl()!=null && !right.getRightUrl().trim().equals("")){filterChainDefinitionMap.put(right.getRightUrl(),"perms["+right.getRightCode()+"]");}}//配置认证访问:其他资源(URL)必须认证通过才能访问;filterChainDefinitionMap.put("/**","authc"); //必须放在过滤器链的最后面shiroFilterFactory.setFilterChainDefinitionMap(filterChainDefinitionMap);return shiroFilterFactory;}
//    @Bean(name = "shiroDialect")
//    public ShiroDialect shiroDialect(){//thymeleaf页面上使用shiro标签
//        return new ShiroDialect();
//    }
}

 认证流程:

Shiro 是一个强大而灵活的 Java 安全框架,其认证流程主要包括以下步骤:

一、用户发起请求

你向应用程序发起一个需要认证的请求,比如访问一个受保护的页面或调用一个需要特定权限的服务。

二、Subject 被创建

  1. Shiro 会为当前请求创建一个 Subject 对象。Subject 代表当前 “用户”,可以是实际的用户,也可以是一个服务或系统。
  2. 这个 Subject 对象通常与当前的安全上下文相关联,包含了关于用户身份和权限的信息。

三、获取 SecurityManager

  1. Subject 会向 SecurityManager 请求认证和授权服务。
  2. SecurityManager 是 Shiro 的核心组件,负责管理所有的安全操作。

四、调用 Authenticator

  1. SecurityManager 将认证任务委托给 Authenticator。
  2. Authenticator 负责执行实际的认证操作。

五、收集用户提交的凭证

  1. 如果请求需要认证,通常会要求用户提供用户名和密码等凭证。
  2. 这些凭证会被收集并传递给 Authenticator 进行验证。

六、执行认证

  1. Authenticator 会根据配置的认证策略来验证用户提交的凭证。
  2. 常见的认证策略包括使用数据库、LDAP 目录或其他数据源来验证用户身份。
  3. 如果认证成功,Authenticator 会返回一个包含用户身份信息的 AuthenticationToken。

七、设置用户身份

  1. Subject 会接收 AuthenticationToken,并将用户身份设置为已认证状态。
  2. 此时,Subject 可以代表已认证的用户执行后续的操作。

八、访问控制

  1. 在用户身份被认证后,Shiro 会根据用户的权限进行访问控制。
  2. 如果用户试图访问一个受保护的资源,但没有足够的权限,Shiro 会抛出相应的异常或拒绝访问。

总之,Shiro 的认证流程通过 Subject、SecurityManager、Authenticator 等组件的协作,实现了对用户身份的验证和访问控制,确保只有经过认证和授权的用户才能访问受保护的资源。

 

 


http://www.mrgr.cn/news/51627.html

相关文章:

  • 2. MySQL数据库基础
  • 本地typora编辑的.md文件上传到【语雀】->【CSDN】
  • Java-IO流使用场景
  • 4、CSS3笔记
  • 【Web前端概述】
  • mybatis-plus的Iservice接口的save方法,返回true,但是数据库表里却没有看到新记录
  • torchserve在转转GPU推理服务架构下的实践
  • 教学资料管理|基于springBoot的教学资料管理系统设计与实现(附项目源码+论文+数据库)
  • 设置静置情况下getCurrentCalls方法为何一直打印?
  • 25届计算机保研经验贴(中末九保清北及华五人、自动化所、北邮、港中文)
  • 【推导过程】常用连续分布的数学期望、方差、特征函数
  • Python--plt.errorbar学习笔记
  • 多场景多任务建模(三): M2M(Multi-Scenario Multi-Task Meta Learning)
  • H5 Canvas 举牌小人
  • DeepFM模型代码详解
  • rom定制系列------小米6x_澎湃os1.0.28安卓13定制固件修改 刷写过程与界面预览
  • cuda编程模型
  • GStreamer 简明教程(七):实现管道的动态数据流
  • 自定义多级联动选择器指南(uni-app)
  • 力扣之1398.购买了产品A和产品B却没有购买产品C顾客