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

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

![在这里插入图片描述](https://img-
blog.csdnimg.cn/direct/bd12a74a5325462096f95dfbf15952e0.png)

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提供了一些帮助。在你的项目中加入这把保护应用的利剑,让你的应用更加安全可靠!

作者信息

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

题外话

初入计算机行业的人或者大学计算机相关专业毕业生,很多因缺少实战经验,就业处处碰壁。下面我们来看两组数据:

2023届全国高校毕业生预计达到1158万人,就业形势严峻;

国家网络安全宣传周公布的数据显示,到2027年我国网络安全人员缺口将达327万。

一方面是每年应届毕业生就业形势严峻,一方面是网络安全人才百万缺口。

6月9日,麦可思研究2023年版就业蓝皮书(包括《2023年中国本科生就业报告》《2023年中国高职生就业报告》)正式发布。

2022届大学毕业生月收入较高的前10个专业

本科计算机类、高职自动化类专业月收入较高。2022届本科计算机类、高职自动化类专业月收入分别为6863元、5339元。其中,本科计算机类专业起薪与2021届基本持平,高职自动化类月收入增长明显,2022届反超铁道运输类专业(5295元)排在第一位。

具体看专业,2022届本科月收入较高的专业是信息安全(7579元)。对比2018届,电子科学与技术、自动化等与人工智能相关的本科专业表现不俗,较五年前起薪涨幅均达到了19%。数据科学与大数据技术虽是近年新增专业但表现亮眼,已跻身2022届本科毕业生毕业半年后月收入较高专业前三。五年前唯一进入本科高薪榜前10的人文社科类专业——法语已退出前10之列。

“没有网络安全就没有国家安全”。当前,网络安全已被提升到国家战略的高度,成为影响国家安全、社会稳定至关重要的因素之一。

网络安全行业特点

1、就业薪资非常高,涨薪快 2022年猎聘网发布网络安全行业就业薪资行业最高人均33.77万!

img

2、人才缺口大,就业机会多

2019年9月18日《中华人民共和国中央人民政府》官方网站发表:我国网络空间安全人才 需求140万人,而全国各大学校每年培养的人员不到1.5W人。猎聘网《2021年上半年网络安全报告》预测2027年网安人才需求300W,现在从事网络安全行业的从业人员只有10W人。
img

行业发展空间大,岗位非常多

网络安全行业产业以来,随即新增加了几十个网络安全行业岗位︰网络安全专家、网络安全分析师、安全咨询师、网络安全工程师、安全架构师、安全运维工程师、渗透工程师、信息安全管理员、数据安全工程师、网络安全运营工程师、网络安全应急响应工程师、数据鉴定师、网络安全产品经理、网络安全服务工程师、网络安全培训师、网络安全审计员、威胁情报分析工程师、灾难恢复专业人员、实战攻防专业人员…

职业增值潜力大

网络安全专业具有很强的技术特性,尤其是掌握工作中的核心网络架构、安全技术,在职业发展上具有不可替代的竞争优势。

随着个人能力的不断提升,所从事工作的职业价值也会随着自身经验的丰富以及项目运作的成熟,升值空间一路看涨,这也是为什么受大家欢迎的主要原因。

从某种程度来讲,在网络安全领域,跟医生职业一样,越老越吃香,因为技术愈加成熟,自然工作会受到重视,升职加薪则是水到渠成之事。

黑客&网络安全如何学习

今天只要你给我的文章点赞,我私藏的网安学习资料一样免费共享给你们,来看看有哪些东西。

1.学习路线图

行业发展空间大,岗位非常多

网络安全行业产业以来,随即新增加了几十个网络安全行业岗位︰网络安全专家、网络安全分析师、安全咨询师、网络安全工程师、安全架构师、安全运维工程师、渗透工程师、信息安全管理员、数据安全工程师、网络安全运营工程师、网络安全应急响应工程师、数据鉴定师、网络安全产品经理、网络安全服务工程师、网络安全培训师、网络安全审计员、威胁情报分析工程师、灾难恢复专业人员、实战攻防专业人员…

职业增值潜力大

网络安全专业具有很强的技术特性,尤其是掌握工作中的核心网络架构、安全技术,在职业发展上具有不可替代的竞争优势。

随着个人能力的不断提升,所从事工作的职业价值也会随着自身经验的丰富以及项目运作的成熟,升值空间一路看涨,这也是为什么受大家欢迎的主要原因。

从某种程度来讲,在网络安全领域,跟医生职业一样,越老越吃香,因为技术愈加成熟,自然工作会受到重视,升职加薪则是水到渠成之事。

黑客&网络安全如何学习

今天只要你给我的文章点赞,我私藏的网安学习资料一样免费共享给你们,来看看有哪些东西。

1.学习路线图

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

攻击和防守要学的东西也不少,具体要学的东西我都写在了上面的路线图,如果你能学完它们,你去就业和接私活完全没有问题。

2.视频教程

网上虽然也有很多的学习资源,但基本上都残缺不全的,这是我自己录的网安视频教程,上面路线图的每一个知识点,我都有配套的视频讲解。

内容涵盖了网络安全法学习、网络安全运营等保测评、渗透测试基础、漏洞详解、计算机基础知识等,都是网络安全入门必知必会的学习内容。

3.技术文档和电子书

技术文档也是我自己整理的,包括我参加大型网安行动、CTF和挖SRC漏洞的经验和技术要点,电子书也有200多本,由于内容的敏感性,我就不一一展示了。

4.工具包、面试题和源码

“工欲善其事必先利其器”我为大家总结出了最受欢迎的几十款款黑客工具。涉及范围主要集中在 信息收集、Android黑客工具、自动化工具、网络钓鱼等,感兴趣的同学不容错过。

还有我视频里讲的案例源码和对应的工具包,需要的话也可以拿走。

这些题目都是大家在面试深信服、奇安信、腾讯或者其它大厂面试时经常遇到的,如果大家有好的题目或者好的见解欢迎分享。

参考解析:深信服官网、奇安信官网、Freebuf、csdn等

内容特点:条理清晰,含图像化表示更加易懂。

内容概要:包括 内网、操作系统、协议、渗透测试、安服、漏洞、注入、XSS、CSRF、SSRF、文件上传、文件下载、文件包含、XXE、逻辑漏洞、工具、SQLmap、NMAP、BP、MSF…

img

因篇幅有限,仅展示部分资料,需要点击下方链接即可前往获取

如果你对网络安全入门感兴趣,那么你需要的话可以点击这里👉网络安全重磅福利:入门&进阶全套282G学习资源包免费分享!

  • 18
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值