安全之剑:深度解析 Apache Shiro 框架原理与使用指南

这篇具有很好参考价值的文章主要介绍了安全之剑:深度解析 Apache Shiro 框架原理与使用指南。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

在现代软件开发中,安全性一直是至关重要的一个方面。随着网络攻击和数据泄露的不断增加,我们迫切需要一种强大而灵活的安全框架来保护我们的应用。Shiro框架就是这样一把利剑,它能够轻松地集成到你的项目中,为你的应用提供可靠的安全性保护。

apache shiro,安全,apache,golang,java,go,前端,windows

Shiro框架概述

Apache Shiro是一个强大且易用的Java安全框架,提供了身份验证、授权、密码学和会话管理等功能。它被广泛用于保护各种类型的应用程序,包括Web应用、RESTful服务、移动应用和大型企业级应用。使用Shiro,你可以将安全性集成到应用程序中而不必担心复杂的实现细节。

Shiro的核心概念

在深入了解Shiro的原理之前,我们先来了解一下Shiro的一些核心概念:

  • Subject(主体):代表当前用户,可以是一个人、设备或者其他与应用交互的实体。Subject封装了与安全性相关的操作,如身份验证和授权。

  • SecurityManager(安全管理器):负责管理所有Subject,是Shiro的核心。它协调各种安全组件的工作,确保安全性的全面性。

  • Realm(域):负责验证Subject的身份,并提供与授权数据交互。可以将Realm看作是安全数据源。

  • Authentication(身份验证):验证Subject的身份是否合法。通常包括用户名密码验证、多因素认证等。

  • Authorization(授权):确定Subject是否有权限执行特定的操作。授权是安全框架的另一个关键方面。

  • Session Management(会话管理):处理用户的会话,确保安全地管理用户的状态信息。

Shiro的优势

Shiro的优势在于其简单性和灵活性。相较于其他安全框架,Shiro采用了非常直观的API和清晰的架构,使得开发者能够更轻松地理解和使用。此外,Shiro的可扩展性也是其强大之处,你可以根据自己的需求轻松地定制和扩展功能。

Shiro的安装与配置

现在,让我们一起来了解如何在项目中引入Shiro,并进行基本的配置。在这里,我以一个基于Spring Boot的Web应用为例进行演示。

步骤1:引入Shiro依赖

首先,在你的项目中引入Shiro的依赖。如果你使用Maven,可以在pom.xml中添加以下依赖:

<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-spring-boot-starter</artifactId>
    <version>1.8.0</version> <!-- 请替换为最新版本 -->
</dependency>

步骤2:配置Shiro

在Spring Boot项目中,Shiro的配置通常是通过ShiroConfig类来完成的。创建一个ShiroConfig类,并配置相关的Bean:

@Configuration
public class ShiroConfig {

    @Bean
    public DefaultWebSecurityManager securityManager() {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        // 设置Realm
        securityManager.setRealm(myRealm());
        return securityManager;
    }

    @Bean
    public MyRealm myRealm() {
        return new MyRealm();
    }

    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultWebSecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean();
        shiroFilter.setSecurityManager(securityManager);
        // 配置拦截规则等
        // ...
        return shiroFilter;
    }
}

在这个例子中,我们配置了一个DefaultWebSecurityManager,并设置了自定义的MyRealm作为Realm。同时,还配置了ShiroFilterFactoryBean,用于定义拦截规则。

步骤3:编写Realm

创建一个继承AuthorizingRealm的自定义Realm类,用于处理身份验证和授权逻辑:

public class MyRealm extends AuthorizingRealm {

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        // 处理身份验证逻辑,例如从数据库中查询用户信息
        // ...
    }

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        // 处理授权逻辑,例如从数据库中查询用户权限信息
        // ...
    }
}

doGetAuthenticationInfo方法中,你可以根据传入的AuthenticationToken进行用户身份验证;而在doGetAuthorizationInfo方法中,你可以根据PrincipalCollection获取用户的权限信息。

Shiro的身份验证

Shiro的身份验证是整个安全框架的核心。下面,让我们通过一个简单的示例来演示如何在Shiro中进行用户身份验证。

// 获取当前用户
Subject currentUser = SecurityUtils.getSubject();

// 创建一个身份验证令牌
UsernamePasswordToken token = new UsernamePasswordToken("username", "password");

try {
    // 调用登录方法进行身份验证
    currentUser.login(token);
    // 身份验证成功,执行其他逻辑
} catch (AuthenticationException e) {
    // 身份验证失败,处理异常
}

在这个例子中,我们首先获取当前用户的Subject,然后创建一个UsernamePasswordToken,设置用户名和密码。接着,调用currentUser.login(token)方法进行身份验证,如果身份验证失败,将会抛出AuthenticationException异常,你可以在catch块中处理相应的异常信息。

为了更好地了解Shiro的身份验证过程,让我们详细讨论一下MyRealm中的doGetAuthenticationInfo方法。这个方法是Shiro用来处理身份验证逻辑的地方。

@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
    // 将AuthenticationToken转换为UsernamePasswordToken
    UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
    
    // 从token中获取用户名
    String username = token.getUsername();
    
    // 在实际项目中,这里通常是从数据库中根据用户名查询用户信息
    // 这里为了演示,我们假设存在一个用户
    if (!"username".equals(username)) {
        throw new UnknownAccountException("用户不存在");
    }
    
    // 假设数据库中的密码是经过加密的,这里为了演示使用明文密码
    String password = "password";
    
    // 返回认证信息,包括用户名和密码
    return new SimpleAuthenticationInfo(username, password, getName());
}

在这个简单的身份验证逻辑中,我们通过UsernamePasswordToken获取到用户输入的用户名,然后假设在数据库中查询到了对应的用户信息。如果用户名不存在,抛出UnknownAccountException异常表示用户未知。如果存在用户,将明文密码返回给Shiro框架,Shiro会将用户输入的密码与数据库中的密码进行匹配。

需要注意的是,在实际项目中,密码存储应该是经过安全加密的,而不是明文存储。Shiro提供了一些常见的加密算法,你可以根据项目需求选择适当的算法。

Shiro的授权

Shiro的授权功能使我们能够精确地定义用户对应用程序中资源的访问权限。通过授权,我们可以防止未经授权的用户访问敏感数据或执行危险操作。

授权的基本概念

在Shiro中,授权通常分为两个步骤:角色授权权限授权

  • 角色授权:将用户分配给一个或多个角色,每个角色代表一组相关的权限。用户通过角色间接获得权限。

  • 权限授权:直接将权限赋予用户,允许用户执行具体的操作。权限是对应用程序中资源的访问控制。

示例:角色授权

让我们通过一个简单的例子来演示如何在Shiro中进行角色授权。

首先,在MyRealm中重写doGetAuthorizationInfo方法:

@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
    SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
    
    // 获取当前用户的用户名
    String username = (String) principalCollection.getPrimaryPrincipal();
    
    // 假设在数据库中查询到该用户的角色信息
    Set<String> roles = new HashSet<>();
    roles.add("admin"); // 用户拥有admin角色
    
    // 将角色信息设置到AuthorizationInfo中
    authorizationInfo.setRoles(roles);
    
    return authorizationInfo;
}

在这个例子中,我们假设用户拥有admin角色。在实际项目中,你需要从数据库中查询用户的角色信息。

然后,在应用程序中,你可以通过以下方式检查用户是否拥有特定角色:

// 获取当前用户
Subject currentUser = SecurityUtils.getSubject();

// 检查用户是否拥有admin角色
if (currentUser.hasRole("admin")) {
    // 用户拥有admin角色,执行相应逻辑
} else {
    // 用户没有admin角色,执行其他逻辑
}

示例:权限授权

现在,让我们看一个授权中的权限授权的例子。

MyRealm中继续完善doGetAuthorizationInfo方法:

@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
    SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
    
    // 获取当前用户的用户名
    String username = (String) principalCollection.getPrimaryPrincipal();
    
    // 假设在数据库中查询到该用户的权限信息
    Set<String> permissions = new HashSet<>();
    permissions.add("user:read"); // 用户拥有读取用户信息的权限
    
    // 将权限信息设置到AuthorizationInfo中
    authorizationInfo.setStringPermissions(permissions);
    
    return authorizationInfo;
}

在这个例子中,我们假设用户拥有user:read权限。同样,你需要从数据库中查询用户的权限信息。

在应用程序中,你可以通过以下方式检查用户是否拥有特定权限:

// 获取当前用户
Subject currentUser = SecurityUtils.getSubject();

// 检查用户是否拥有user:read权限
if (currentUser.isPermitted("user:read")) {
    // 用户拥有user:read权限,执行相应逻辑
} else {
    // 用户没有user:read权限,执行其他逻辑
}

Shiro的会话管理

Shiro提供了灵活且强大的会话管理功能,用于管理用户的会话状态。会话是指用户在系统中的交互期间保持的状态,通常用于存储用户的登录信息、权限信息以及其他相关数据。

会话管理的基本概念

在Shiro中,会话管理主要涉及以下几个方面:

  • 会话创建和销毁:Shiro会自动管理会话的创建和销毁,你可以配置会话的超时时间。

  • 会话存储:会话中存储用户的身份信息、权限信息等,以便于在用户请求之间共享数据。

  • 会话监听:可以通过会话监听器来监听会话的创建、销毁、过期等事件,以执行一些自定义的逻辑。

示例:会话管理

让我们通过一个简单的例子来演示如何在Shiro中进行会话管理。首先,我们需要配置Shiro的会话管理器和会话DAO。

ShiroConfig中添加以下配置:

@Configuration
public class ShiroConfig {

    @Bean
    public DefaultWebSecurityManager securityManager() {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        // 设置Realm
        securityManager.setRealm(myRealm());
        // 设置会话管理器
        securityManager.setSessionManager(sessionManager());
        // 设置会话DAO
        securityManager.setSessionDAO(sessionDAO());
        return securityManager;
    }

    @Bean
    public MyRealm myRealm() {
        return new MyRealm();
    }

    @Bean
    public DefaultWebSessionManager sessionManager() {
        DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
        // 设置全局会话超时时间(毫秒)
        sessionManager.setGlobalSessionTimeout(1800000); // 30分钟
        // 是否在会话过期后自动删除
        sessionManager.setDeleteInvalidSessions(true);
        // 是否开启定时调度器检测过期会话
        sessionManager.setSessionValidationSchedulerEnabled(true);
        return sessionManager;
    }

    @Bean
    public EnterpriseCacheSessionDAO sessionDAO() {
        // 使用企业级缓存SessionDAO,可以替换为其他实现
        EnterpriseCacheSessionDAO sessionDAO = new EnterpriseCacheSessionDAO();
        // 设置缓存名称,根据实际情况配置
        sessionDAO.setActiveSessionsCacheName("shiro-activeSessionCache");
        return sessionDAO;
    }

    // ...其他配置
}

在这个配置中,我们配置了一个DefaultWebSessionManager作为会话管理器,设置了全局会话超时时间为30分钟。同时,我们使用了EnterpriseCacheSessionDAO作为会话DAO,用于存储会话数据。你可以根据项目需求选择不同的会话DAO实现。

接下来,在MyRealm中,我们可以通过重写doGetAuthenticationInfo方法将用户的身份信息存储到会话中:

@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
    // 将AuthenticationToken转换为UsernamePasswordToken
    UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;

    // 从token中获取用户名
    String username = token.getUsername();

    // 在实际项目中,这里通常是从数据库中根据用户名查询用户信息
    // 这里为了演示,我们假设存在一个用户
    if (!"username".equals(username)) {
        throw new UnknownAccountException("用户不存在");
    }

    // 假设数据库中的密码是经过加密的,这里为了演示使用明文密码
    String password = "password";

    // 返回认证信息,包括用户名和密码
    SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(username, password, getName());

    // 获取当前Subject的会话,存储用户身份信息
    Session session = SecurityUtils.getSubject().getSession();
    session.setAttribute("currentUsername", username);

    return authenticationInfo;
}

在这个例子中,我们使用SecurityUtils.getSubject().getSession()获取当前Subject的会话对象,然后将用户名存储到会话的currentUsername属性中。这样,在整个用户会话期间,我们都可以通过SecurityUtils.getSubject().getSession().getAttribute("currentUsername")获取到当前用户的用户名。

Shiro的其他特性

除了上述介绍的核心功能之外,Shiro还提供了许多其他有用的特性,例如密码加密、RememberMe功能、单点登录等。在这里,简单介绍一下其中的一些特性。

密码加密

在真实项目中,用户密码通常不会以明文形式存储在数据库中,而是经过加密处理。Shiro提供了方便的密码加密工具,可以轻松地对密码进行加密和验证。

首先,在MyRealm中,修改doGetAuthenticationInfo方法,将明文密码加密后返回:

@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
    // 将AuthenticationToken转换为UsernamePasswordToken
    UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;

    // 从token中获取用户名
    String username = token.getUsername();

    // 在实际项目中,这里通常是从数据库中根据用户名查询用户信息
    // 这里为了演示,我们假设存在一个用户
    if (!"username".equals(username)) {
        throw new UnknownAccountException("用户不存在");
    }

    // 假设数据库中的密码是经过加密的
    String encryptedPassword = encryptPassword("password");

    // 返回认证信息,包括用户名和加密后的密码
    return new SimpleAuthenticationInfo(username, encryptedPassword, getName());
}

private String encryptPassword(String password) {
    // 使用Shiro提供的密码加密工具
    return new Md5Hash(password).toHex();
}

在这个例子中,我们使用Md5Hash对密码进行MD5加密。你可以根据实际项目需求选择其他加密算法。

RememberMe功能

Shiro的RememberMe功能允许用户在关闭浏览器后仍然保持登录状态。通过简单的配置,我们可以启用RememberMe功能。

ShiroConfig中添加RememberMe的配置:

@Bean
public CookieRememberMeManager rememberMeManager() {
    CookieRememberMeManager rememberMeManager = new CookieRememberMeManager();
    SimpleCookie rememberMeCookie = new SimpleCookie("rememberMe");
    rememberMeCookie.setMaxAge(2592000); // 设置Cookie的有效期,单位秒,这里为30天
    rememberMeManager.setCookie(rememberMeCookie);
    return rememberMeManager;
}

@Bean
public DefaultWebSecurityManager securityManager() {
    DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
    // 设置Realm
    securityManager.setRealm(myRealm());
    // 设置会话管理器
    securityManager.setSessionManager(sessionManager());
    // 设置会话DAO
    securityManager.setSessionDAO(sessionDAO());
    // 设置RememberMe管理器
    securityManager.setRememberMeManager(rememberMeManager());
    return securityManager;
}

在这个配置中,我们创建了一个CookieRememberMeManager,并设置了RememberMe的Cookie名称和有效期。然后将其添加到DefaultWebSecurityManager中。

单点登录

Shiro还支持单点登录(SSO),使用户能够在多个关联的应用程序中使用同一套凭据进行登录。Shiro的单点登录功能可以通过集成其他身份验证和授权提供程序来实现,其中包括OAuth、CAS等。在这里,我们简单介绍一下使用OAuth 2.0的单点登录配置。

首先,在ShiroConfig中添加OAuth的配置:

@Bean
public OAuth2Realm oAuth2Realm() {
    return new OAuth2Realm();
}

@Bean
public DefaultWebSecurityManager securityManager() {
    DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
    // 设置Realm
    securityManager.setRealm(oAuth2Realm());
    // 设置会话管理器
    securityManager.setSessionManager(sessionManager());
    // 设置会话DAO
    securityManager.setSessionDAO(sessionDAO());
    // 设置RememberMe管理器
    securityManager.setRememberMeManager(rememberMeManager());
    return securityManager;
}

在这个配置中,我们创建了一个OAuth2Realm并将其设置为主Realm。OAuth2Realm是一个自定义的Realm,用于处理OAuth 2.0的身份验证和授权。

接下来,实现OAuth2Realm

public class OAuth2Realm extends AuthorizingRealm {

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        // 处理OAuth 2.0的授权逻辑
        // ...
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        // 处理OAuth 2.0的身份验证逻辑
        // ...
    }
}

doGetAuthenticationInfodoGetAuthorizationInfo方法中,你需要实现OAuth 2.0的身份验证和授权逻辑,具体实现方式取决于你使用的OAuth提供商。

这只是Shiro单点登录的一个简单示例,实际上,单点登录可能涉及到更复杂的协议和配置,具体实现方式取决于你的项目需求。

结语

Apache Shiro作为一款强大且灵活的Java安全框架,为我们提供了全面的安全性解决方案。通过本文的介绍,你应该对Shiro的基本原理、使用方法以及一些高级功能有了初步的了解。

在实际项目中,根据具体需求和项目规模,你可以选择使用Shiro来保护你的应用。不仅如此,Shiro的社区活跃,文档详尽,你可以方便地获取支持和解决问题。

希望这篇博客对你理解和使用Shiro提供了一些帮助。在你的项目中加入这把保护应用的利剑,让你的应用更加安全可靠!文章来源地址https://www.toymoban.com/news/detail-845655.html

作者信息

作者 : 繁依Fanyi
CSDN: https://techfanyi.blog.csdn.net
掘金:https://juejin.cn/user/4154386571867191

到了这里,关于安全之剑:深度解析 Apache Shiro 框架原理与使用指南的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 框架漏洞-CVE复现-Apache Shiro+Apache Solr

    什么是框架?        就是别人写好包装起来的一套工具,把你原先必须要写的,必须要做的一些复杂的东西都写好了放在那里,你只要调用他的方法,就可以实现一些本来要费好大劲的功能。          如果网站的功能是采用框架开发的,那么挖掘功能的漏洞就相当于

    2024年02月16日
    浏览(22)
  • Spring Security 和 Apache Shiro 登录安全架构选型

    Spring Security和Apache Shiro都是广泛使用的Java安全框架,它们都提供了许多功能来保护应用程序的安全性,包括身份验证、授权、加密、会话管理等。 Spring Security和Apache Shiro都是非常常用的登录安全框架,两者在登录安全架构的选型上各有特点: Spring Security特点: 与Spring框架深度集

    2024年02月14日
    浏览(25)
  • Apache Shiro RememberMe 1.2.4 反序列化过程命令执行漏洞【原理扫描】

    文章目录 一、分析定位 1. 漏洞描述 2. 项目引发漏洞简述 二、 若依系统 2.1. 版本升级 2.2. 配置文件 2.3. 推荐做法 2.4. 栗子 2.5. 项目场景 三、Gus系统 3.1. shiro版本升级 3.2. 调用重新生成 3.3. 生成工具类 shiro漏洞补充: 一、分析定位 1. 漏洞描述 2. 项目引发漏洞简述 若依/Guns管

    2024年02月15日
    浏览(30)
  • 深度解析Redisson框架的分布式锁运行原理与高级知识点

    分布式系统中的锁管理一直是一个复杂而关键的问 题。在这个领域,Redisson框架凭借其出色的性能和功能成为了开发者的首选之一。本篇博客将深入探讨Redisson框架的分布式锁运行原理以及涉及的高级知识点。通过详细的解释和示例代码,您将更好地理解如何在分布式环境中

    2024年02月09日
    浏览(28)
  • Shiro安全框架简介

    1.1 什么是权限管理 基本上只要涉及到用户参数的系统都要进行权限管理,使用权限管理实现了对用户访问系统的控制,不同的用户访问不同的资源。按照安全规则或者安全策略控制用户访问资源,而且只能访问被授权的资源 权限管理包括认证和授权两部分,当用户访问资源

    2023年04月20日
    浏览(28)
  • shiro 安全(权限)框架

    1.1、概述 Apache Shiro 是一个功能强大且易于使用的 Java 安全(权限)框架。Shiro 可以完成:认证、授权、加密、会话管理、与 Web 集成、缓存 等。借助 Shiro 您可以快速轻松地保护任何应用程序——从最小的移动应用程序到最大的 Web 和企业应用程序。 官网:https://shiro.apache.org/

    2024年02月06日
    浏览(34)
  • JAVA安全框架之shiro

    Apache Shiro 是一个功能强大且易于使用的 Java 安全(权限)框架 。Shiro 可以完 成: 认证、授权、加密、会话管理、与 Web 集成、缓存 等。借助 Shiro 您可以快速轻松 地保护任何应用程序——从最小的移动应用程序到最大的 Web 和企业应用程序。 官网 :https://shiro.apache.org/     s

    2024年02月15日
    浏览(34)
  • SSM+Shiro安全框架整合(完成安全认证--登录+权限授权)+ssm整合shiro前后端分离

    目录 1.搭建SSM框架  1.1.引入相关的依赖 1.2. spring配置文件 1.3. web.xml配置文件 1.4.配置Tomcat并启动 2.ssm整合shiro---认证功能  (1).引入依赖 (2).修改spring配置文件 (3).修改web.xml文件 (4).新建login.jsp(登录页面) (5).新建success.jsp(登录成功后跳转到此) (6).创建User实体类 (7).创建LoginVo

    2024年02月15日
    浏览(36)
  • SSM 整合 Shiro 安全框架【快速入门】

    更改web路径 创建所需目录 属性名与数据库字段名一 一对应 这里只是为了测试项目,还没有进行编码工作 启动tamcat服务 LoginVo

    2024年02月12日
    浏览(33)
  • 请简单介绍一下Shiro框架是什么?Shiro在Java安全领域的主要作用是什么?Shiro主要提供了哪些安全功能

    会话管理(Session Management):Shiro能够管理用户的会话状态,包括会话的创建、维护和销毁。它支持多种会话存储方式(如内存、数据库等),并提供了会话超时、会话失效等机制,以确保会话的安全性。 跨平台集成:Shiro不仅适用于Web应用程序,还可以轻松集成到桌面应用

    2024年04月13日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包