管理权限特权

管理权限
Oracle 用户权限分为两种类型:
系统权限:允许用户在数据库中执行特定的操作。
对象权限:允许用户访问和操作特定的对象。

系统权限

Oracle 数据库中有超过100种不同的系统权限。权限中的 “ANY” 关键字表示用户在任何模式(schema)中都具有该权限。
GRANT 命令用于向用户或一组用户添加权限。
REVOKE 命令用于删除权限。


SQL> desc session_privs
Name        Nul1?        Type 
PRIVILEGE   NOT NULL     VARCHAR2(40)
SQL> SELECT * FROM session_privs; 
PRIVILEGE CREATE SESSION
  1. 描述会话权限视图的结构:
    • desc session_privs;: 这个命令用于显示 session_privs 视图的列信息,包括列名、是否可以为空(NULL)以及数据类型。从输出中我们可以看到,session_privs 视图有一个名为 PRIVILEGE 的列,该列的数据类型是 VARCHAR2(40),并且不允许为空(NOT NULL)。
  2. 查看当前会话的权限:
    • SELECT * FROM session_privs;: 这个命令用于查询当前会话具有的权限。输出显示当前会话具有 CREATE SESSION 权限,这意味着登录的用户有权限创建一个新的数据库会话。这是最基本的权限之一,通常每个用户都会被授予此权限,以便他们能够登录到数据库。
[ oracle@ trainserver "]$ sqlplus /nolog SQL* Plus: Release 9.2.0.4.0 -Production on Thu Mar 19 18:11:31 2009
Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved.
SQL> conn /as sysdba Connected.
SQL> show user USER is "SYS"
SQL> col tablespace_name format a20
SQL> SELECT tablespace_name, contents FROM dba_tablespaces

14 rows selected.      # 登入数据库并且查询表

[ oracle@ trainserver "]$ sqlplus /nolog SQL* Plus: Release 9.2.0.4.0 -Production on Thu Mar 19 18:14:52 2009
Copyright (c) 1982, 2002, Oracle Corporation. A11 rights reserved.
SQL> conn u1/bbk_12345   --登入数据库发现刚创建的数据库无法连接
ERROR: ORA-01045: user U1 lacks CREATE SESSION privilege; logon denied SQL> conn u1/bbk_12345   --增加连接权限后可以连接
Connected.
SQL> create table t(id int);
 create table t(id int)*
ERROR at line 1: ORA-01031: insufficient privileges 
SQL> desc session_privs 
Name        Nul1?     Type 
PRIVILEGE   NOT NULL  VARCHAR2(40)
SQL> SELECT * FROM session_privs;    # 查询权限
PRIVILEGE CREATE SESSION SQL>

14 rows selected.

--创建用户
SQL> create user u1 identified by bbk_12345 default tablespace mytbs quota unlimited o n mytbs;
User created.
SQL> create user u2 identified by bbk_12345 default tablespace mytbs quota unlimited o n mytbs; 
User created.
SQL> create user u3 identified by bbk_12345 default tablespace mytbs quota unlimited o n mytbs;

类别和权限示例

类别权限描述
INDEXCREATE ANY INDEX允许用户在任何用户的表上创建索引。
ALTER ANY INDEX允许用户修改任何用户的索引。
DROP ANY INDEX允许用户删除任何用户的索引。
TABLECREATE TABLE允许用户创建表。
CREATE ANY TABLE允许用户在任何表空间中创建表。
ALTER ANY TABLE允许用户修改任何用户的表。
DROP ANY TABLE允许用户删除任何用户的表。
SELECT ANY TABLE允许用户查询任何用户的表中的数据。
DELETE ANY TABLE允许用户删除任何用户的表中的数据。
UPDATE ANY TABLE允许用户更新任何用户的表中的数据。
SESSIONCREATE SESSION允许用户建立数据库会话。
ALTER SESSION允许用户修改会话的参数。
RESTRICTED SESSION允许用户在受限模式下建立会话。
TABLESPACECREATE TABLESPACE允许用户创建新的表空间。
ALTER TABLESPACE允许用户修改表空间。
DROP TABLESPACE允许用户删除表空间。
UNLIMITED TABLESPACE允许用户在表空间中分配无限量的空间(通常不推荐授予此权限)。

系统权限限制
参数 07_DICTIONARY_ACCESSIBILITY

  • 控制对系统权限的限制。
  • 如果设置为 TRUE,则允许访问 SYS 模式中的对象。
  • 默认设置为 FALSE:确保允许访问任何模式的系统权限不会允许访问 SYS 模式。
-- 显示当前用户
SQL> show user; -- 输出当前登录的用户,此处显示为系统管理员 "SYS"

-- 显示参数 O7 的值
SQL> show parameter o7; -- 显示参数 07DICTIONARYACCESSIBILITY 的当前值,此处为 FALSE

-- 正确修改参数 07DICTIONARYACCESSIBILITY 的值
SQL> alter system set "07_DICTIONARY_ACCESSIBILITY"=true scope=spfile; -- 将参数设置为 TRUE,并指定更改将在服务器参数文件中生效

-- 立即关闭数据库
SQL> shutdown immediate; -- 立即关闭数据库,并在完成后卸载数据库

偷取权限

-- 查询当前会话的权限
SQL> select * from session_privs;
-- 输出当前会话具有的权限列表
-- 查询当前会话的角色
SQL> select * from session_roles;
-- 输出当前会话具有的角色列表
-- 创建一个存储过程,名为 h1,参数为 h1_str,该过程执行传入的 SQL 语句
SQL> create procedure system.h1(h1_str in varchar2) as
2 begin
3 execute immediate h1_str;
4 end;
5/
-- 创建成功,存储过程 h1 可以执行任意传入的 SQL 语句
-- 执行存储过程 h1,传入的参数为授权 DBA 角色给 hacker 的 SQL 语句
SQL> execute system.h1(' grant dba to hacker');
-- PL/SQL 过程执行成功,可能已将 DBA 角色授予了 hacker 用户
-- 再次查询当前会话的权限
SQL> select * from session_privs;
-- 输出当前会话具有的权限列表,注意权限列表中可能增加了 UNLIMITED TABLESPACE

请注意,上述代码块中的 execute system.h1(' grant dba to hacker'); 命令存在安全风险,因为它允许执行任意 SQL 语句,这可能导致未授权的权限提升。在生产环境中应避免使用此类代码。此外,UNLIMITED TABLESPACE 权限的出现可能表明执行了未显示的授权操作,这同样需要谨慎处理。

对象权限

对象权限视图序列过程
更改(ALTER)
删除(DELETE)
执行(EXECUTE)
索引(INDEX)
插入(INSERT)
引用(REFERENCES)
选择(SELECT)
更新(UPDATE)

授权对象权限 使用GRANT命令来授权对象权限。授权者必须在授权者的模式中,或者授权者必须具有授权选项。
GRANT EXECUTE ON dbms_output TO jeff;
授予jeff对dbms_output包的执行权限。
GRANT UPDATE ON emi.customers TO jeff WITH GRANT OPTION;
授予jeff对emi模式中customers表的更新权限,并且jeff也有权限将这个更新权限授予其他用户。授权传递性

如何授予对象权限(Object Privileges),以及与视图相关的权限管理。
  1. 权限授予对象
    • 对象权限可以授予给用户、角色或者PUBLIC(即所有用户)。
  2. 视图权限和底层表权限
    • 如果一个视图引用了另一个用户的表或视图,那么要在这个视图上授予其他用户权限,你需要对视图所依赖的底层表拥有带有GRANT OPTION的权限。
    • 例如,如果JOHN拥有一个视图,该视图引用了JAMES的表,那么为了将SELECT权限授予视图给其他用户,JOHN必须拥有JAMES表上的SELECT权限,并且这个权限是带有GRANT OPTION的。
  3. 表锁定权限
    • 任何在表上收到的对象权限都会授予给被授权者锁定该表的能力。
  4. 列级SELECT权限
    • 不能直接在表的列上指定SELECT权限。如果需要授予列级的SELECT权限,应该创建一个包含所需列的视图,然后在视图上授予SELECT权限。
      以下是这些规则的代码示例:
-- 假设JAMES拥有一个表,JOHN想要创建一个视图并授予他人权限
-- JAMES授予JOHN在表上的SELECT权限,带有GRANT OPTION
SQL> GRANT SELECT ON JAMES.table_name TO JOHN WITH GRANT OPTION;
-- JOHN创建视图
SQL> CREATE VIEW john_view AS SELECT * FROM JAMES.table_name;
-- JOHN现在可以在视图上授予其他用户SELECT权限
SQL> GRANT SELECT ON john_view TO some_other_user;

授予对象特权

你可以使用ALL或ALL PRIVILEGES来授予对象上所有可用的权限。即使你拥有DBA权限,要授予其他用户拥有的对象上的权限,你也必须已经被授予该对象上相应的带有GRANT OPTION的权限。
可以在一个语句中向多个用户和/或角色授予多个权限
以下是相应的SQL命令示例:

-- 授予JAMES对CUSTOMER表的所有权限
SQL> GRANT ALL ON CUSTOMER TO JAMES;
-- 在一个语句中向多个用户和角色授予多个权限
SQL> GRANT INSERT, UPDATE, SELECT ON CUSTOMER TO ADMIN_ROLE, JULIE, SCOTT;  --系统特权和对象特权不能混着赋予

这些命令展示了如何在数据库中高效地管理权限,确保只有授权的用户和角色能够执行特定的数据库操作。使用WITH GRANT OPTION时,需要谨慎,因为这允许被授权者将权限进一步授予其他用户。

预定义角色

角色名称描述
CONNECT, RESOURCE, DBA这些角色用于向后兼容性
EXP_FULL_DATABASE导出数据库的权限
IMP_FULL_DATABASE导入数据库的权限
DELETE_CATALOG_ROLE数据字典表上的DELETE权限
EXECUTE_CATALOG_ROLE数据字典包上的EXECUTE权限
SELECT_CATALOG_ROLE数据字典表上的SELECT权限

预定义角色及权限

角色名称权限描述
CONNECT连接到数据库的权限,可以创建集群、数据库链接、序列、同义词、表和视图,以及修改会话。
RESOURCE创建集群、表和序列的权限,以及创建程序化对象如存储过程、函数、包、索引类型、类型、触发器和操作符的权限。
DBA所有系统权限,并带有ADMIN选项,可以将系统权限授予数据库的其他用户或角色。
SELECT_CATALOG_ROLE查询数据字典视图和表的权限。
EXECUTE_CATALOG_ROLE执行数据字典包(系统拥有的包)的权限。
DELETE_CATALOG_ROLE删除或重新创建数据字典包的权限。
EXP_FULL_DATABASE使用导出工具(Export utility)进行数据库的全量导出和增量导出的权限。
IMP_FULL_DATABASE使用导入工具(Import utility)执行全量数据库导入的权限。这是一个非常强大的角色。

获取角色的所有信息

-- 查询角色基本信息
SELECT * FROM DBA_ROLES WHERE ROLE = 'YOUR_ROLE_NAME';
-- 查询角色被授予的系统权限
SELECT * FROM DBA_SYS_PRIVS WHERE GRANTEE = 'YOUR_ROLE_NAME';
-- 查询角色被授予的对象权限
SELECT * FROM DBA_TAB_PRIVS WHERE GRANTEE = 'YOUR_ROLE_NAME';
-- 查询角色被授予的角色权限
SELECT * FROM DBA_ROLE_PRIVS WHERE GRANTEE = 'YOUR_ROLE_NAME';
-- 查询哪些用户或角色被授予了这个角色
SELECT * FROM DBA_ROLE_PRIVS WHERE GRANTED_ROLE = 'YOUR_ROLE_NAME';
  • 例子
    以下是您提供的 SQL 命令和查询的整理,包括代码块和必要的注释。我已经更正了一些格式错误,并添加了注释来解释每个命令的作用。
-- 授予角色 r1 创建会话的权限
SQL> GRANT CREATE SESSION TO r1;
Grant succeeded.
-- 将角色 r1 授予用户 u1
SQL> GRANT r1 TO u1;
Grant succeeded.
-- 授予角色 r2 创建表的权限
SQL> GRANT CREATE TABLE TO r2;
Grant succeeded.
-- 将角色 r2 授予用户 u1
SQL> GRANT r2 TO u1;
Grant succeeded.
-- 描述角色角色权限视图 role_role_privs 的结构
SQL> DESC role_role_privs;
Name       Null?    Type
---------- -------- ----------------------------
ROLE       NOT NULL VARCHAR2(30)
GRANTED_ROLE NOT NULL VARCHAR2(30)
ADMIN_OPTION          VARCHAR2(3)
-- 查询角色 r1 被授予了哪些角色权限
SQL> SELECT * FROM role_role_privs WHERE role='R1';
ROLE       GRANTED_ROLE ADM
---------- ------------ ---
R1         R2           NO
-- 查询角色 r2 被授予了哪些角色权限(没有结果)
SQL> SELECT * FROM role_role_privs WHERE role='R2';
no rows selected
-- 描述角色系统权限视图 role_sys_privs 的结构
SQL> DESC role_sys_privs;
Name       Null?    Type
---------- -------- ----------------------------
ROLE       NOT NULL VARCHAR2(30)
PRIVILEGE  NOT NULL VARCHAR2(40)
ADMIN_OPTION          VARCHAR2(3)
-- 描述角色表权限视图 role_tab_privs 的结构
SQL> DESC role_tab_privs;
Name       Null?    Type
---------- -------- ----------------------------
ROLE       NOT NULL VARCHAR2(30)
OWNER      NOT NULL VARCHAR2(30)
TABLE_NAME NOT NULL VARCHAR2(30)
COLUMN_NAME          VARCHAR2(30)
PRIVILEGE  NOT NULL VARCHAR2(40)
GRANTABLE           VARCHAR2(3)
-- 查询以 'RA' 开头的角色拥有的系统权限
SQL> SELECT * FROM role_sys_privs WHERE role LIKE 'RA%';
-- 重复描述角色角色权限视图 role_role_privs 的结构
SQL> DESC role_role_privs;
Name       Null?    Type
---------- -------- ----------------------------
ROLE       NOT NULL VARCHAR2(30)
GRANTED_ROLE NOT NULL VARCHAR2(30)
ADMIN_OPTION          VARCHAR2(3)
-- 查询角色 r1 被授予了哪些角色权限(重复查询)
SQL> SELECT * FROM role_role_privs WHERE role='R1';
ROLE       GRANTED_ROLE ADM
---------- ------------ ---
R1         R2           NO
-- 查询角色 r2 被授予了哪些角色权限(没有结果,语法错误已更正)
SQL> SELECT * FROM role_role_privs WHERE role='R2';
no rows selected
-- 描述角色系统权限视图 role_sys_privs 的结构(重复描述)
SQL> DESC role_sys_privs;
Name       Null?    Type
---------- -------- ----------------------------
ROLE       NOT NULL VARCHAR2(30)
PRIVILEGE  NOT NULL VARCHAR2(40)
ADMIN_OPTION          VARCHAR2(3)
-- 描述角色表权限视图 role_tab_privs 的结构(不完整,已更正)
SQL> DESC role_tab_privs;
Name       Null?    Type
---------- -------- ----------------------------
ROLE       NOT NULL VARCHAR2(30)
OWNER      NOT NULL VARCHAR2(30)
TABLE_NAME NOT NULL VARCHAR2(30)
COLUMN_NAME          VARCHAR2(30)
PRIVILEGE  NOT NULL VARCHAR2(40)
GRANTABLE           VARCHAR2(3)

请注意,以上 SQL 命令块中的 DESCDESCRIBE 的缩写,用于描述表的结构。

缺省(default)角色

  • 用户可以被分配许多角色。
  • 用户可以被分配一个默认角色。
  • 限制用户默认角色的数量。
-- 将hr_clerk和oe_clerk设置为用户scott的默认角色
ALTER USER scott DEFAULT ROLE hr_clerk, oe_clerk;
-- 将所有角色设置为用户scott的默认角色
ALTER USER scott DEFAULT ROLE ALL;
-- 将除了hr_clerk之外的所有角色设置为用户scott的默认角色
ALTER USER scott DEFAULT ROLE ALL EXCEPT hr_clerk;
-- 取消用户scott的所有默认角色
ALTER USER scott DEFAULT ROLE NONE;
  • 可以通过ALTER USER命令为用户设置默认角色。
  • 当用户登录数据库时,默认角色会自动被激活,无需用户手动启用。
  • 通过指定DEFAULT ROLE,可以控制用户在登录时自动获得哪些角色的权限。
  • 使用ALL关键字可以设置所有角色为默认角色。
  • 使用ALL EXCEPT可以设置除特定角色外的所有其他角色为默认角色。
  • 使用NONE可以取消所有默认角色的设置,这样用户在登录后将不会自动获得任何角色的权限。

管理角色启用和禁用

  • 禁用角色以临时撤销用户的角色。
  • 启用角色以临时授予权限。
  • 使用SET ROLE命令来启用和禁用角色。
  • 默认角色在用户登录时自动启用。
  • 启用角色可能需要密码。
    中文解释:
  • 禁用角色:可以通过禁用角色来临时撤销已经赋予用户的角色权限。禁用后,用户将无法使用该角色所包含的权限,直到角色被重新启用。
  • 启用角色:启用角色可以临时地给用户授予权限。一旦角色被启用,用户就可以执行该角色所允许的操作。
  • SET ROLE命令SET ROLE命令用于在会话中启用或禁用角色。使用此命令,可以控制用户在当前会话中的权限。
  • 默认角色:在用户登录数据库时,默认角色会自动启用,无需用户执行任何操作即可使用这些角色的权限。
  • 角色启用密码:某些角色可能需要密码才能启用。这是为了增加安全性,确保只有知道密码的用户才能使用这些角色。
-- 禁用角色
SET ROLE role_name DISABLE;
-- 启用角色
SET ROLE role_name;
-- 如果角色需要密码,则启用时需提供密码
SET ROLE role_name IDENTIFIED BY password;

-- 启用hr_clerk角色
SET ROLE hr_clerk;
-- 启用oe_clerk角色,并指定密码为'order'
SET ROLE oe_clerk IDENTIFIED BY order;
-- 启用所有角色,除了oe_clerk
SET ROLE ALL EXCEPT oe_clerk;
  1. SET ROLE hr_clerk;
    • 此命令用于在当前会话中启用hr_clerk角色。一旦执行,用户将获得hr_clerk角色所包含的所有权限。
  2. SET ROLE oe_clerk IDENTIFIED BY order;
    • 此命令用于在当前会话中启用oe_clerk角色,但前提是提供了正确的密码order。如果角色被设置为需要密码才能启用,则必须提供密码。
  3. SET ROLE ALL EXCEPT oe_clerk;
    • 此命令用于在当前会话中启用除oe_clerk之外的所有角色。这意味着用户将获得除oe_clerk角色之外的所有角色的权限。
      请注意,这些命令是在SQL会话中执行的,它们只影响当前会话的权限设置,不会更改用户的长期权限配置。此外,启用角色时,如果角色被设置为需要密码,则必须提供正确的密码,否则命令将失败。

删除角色

以下是删除角色的详细说明,采用代码块和注释的形式:

-- 删除名为 'hr manager' 的角色
DROP ROLE 'hr manager';

在此SQL命令中:

  • DROP ROLE 是用来删除角色的SQL语句。
  • 'hr manager' 是要删除的角色名称。注意,角色名称通常需要用单引号括起来,特别是当名称包含空格或其他特殊字符时。
    在执行此操作之前,需要考虑以下几点:
  • 必须具有足够的权限,即拥有ADMIN OPTION权限或DROP ANY ROLE系统权限。
  • 删除角色会从所有拥有该角色的用户和角色中移除它。
  • 删除角色后,所有依赖该角色的权限都将被撤销。
  • 确保没有用户正在使用该角色,因为删除角色后,这些用户将失去与该角色关联的所有权限。
  • 如果有其他角色继承或依赖于要删除的角色,可能需要先调整这些角色的权限设置。

应用角色(Application Roles)

应用角色(Application Roles)是可以通过特定的PL/SQL包来启用。应用角色通常用于应用程序中,以提供对数据库对象的精细访问控制。以下是对您提供的SQL命令的解释:

CREATE ROLE admin_role IDENTIFIED USING hr.employee;

这条SQL命令的含义如下:

  • CREATE ROLE:这是用来创建一个新角色的SQL语句。
  • admin_role:这是你想要创建的角色名称。在这个例子中,角色被命名为admin_role
  • IDENTIFIED USING:这个子句指定了用于启用该角色的PL/SQL包。这意味着只有当指定的PL/SQL包执行时,角色admin_role才能被激活。
  • hr.employee:这是指定PL/SQL包的名称,该包必须存在于hr模式(schema)中,并且必须有一个过程或函数能够控制角色的启用。通常,这个包会包含一些逻辑来验证用户的身份,并在验证通过后启用角色。
    在创建应用角色之后,通常需要在PL/SQL包中实现相应的逻辑来启用该角色。例如,包hr.employee可能包含以下代码:
CREATE OR REPLACE PACKAGE hr.employee AS
  PROCEDURE enable_admin_role;
END employee;
/
CREATE OR REPLACE PACKAGE BODY hr.employee AS
  PROCEDURE enable_admin_role IS
  BEGIN
    -- 这里可以添加用户验证逻辑
    -- 如果验证通过,则启用角色
    EXECUTE IMMEDIATE 'SET ROLE admin_role';
  END enable_admin_role;
END employee;
/

在这个例子中,enable_admin_role过程会在用户验证通过后执行SET ROLE admin_role;命令,从而启用admin_role角色。
请注意,使用应用角色时,应当确保只有授权的用户能够执行启用角色的PL/SQL包,以防止未授权访问。


在这里插入图片描述
层次级设计方法。把privileges理解成原子级的操作,然后按照分层次的方法分成两类角色,一类是应用程序角色,比如上图中的工资角色和好处(福利)角色;另一类是用户角色,根据这些角色的职责把应用程序角色划分给用户角色。

在这里插入图片描述

默认角色创建指南:

在一个例子中,有两种方式可以访问数据库,一种是PL/sql,一种是提供的应用程序接口。想要安全的保护数据,有两种方法:一是让用户只使用应用程序接口的方式。另一种是让通过PL/sql方式访问的角色的权限只有查询,而非缺省的角色(需要密码的)被应用程序调用。

一些视图

DBA_ROLES

  • ROLE:角色的名称。
  • PASSWORD_REQUIRED:角色是否需要密码。
  • AUTHENTICATION_TYPE:角色的认证类型。
  • COMMON:指示角色是否为公共角色。
  • ORACLE_MAINTAINED:指示角色是否由Oracle维护。
  • IMPLICIT:指示角色是否是隐式创建的。
  • CREATED:角色创建的日期和时间。
  • LAST_DROPPED:角色最后一次被删除的日期和时间(如果曾经被删除过)。
    功能:这个视图提供了数据库中所有角色的列表和相关信息。

DBA_ROLE_PRIVS

  • GRANTEE:被授予权限的用户或角色。
  • GRANTED_ROLE:授予给用户或角色的角色。
  • ADMIN_OPTION:指示是否授予了管理员选项,允许授予权限给其他用户。
  • DELEGATE_OPTION:指示是否允许角色被委托。
    功能:这个视图显示了哪些角色被授予了哪些用户或角色,以及相关的管理选项。

ROLE_ROLE_PRIVS

  • ROLE:拥有其他角色的角色。
  • GRANTED_ROLE:被授予的角色。
  • ADMIN_OPTION:指示是否授予了管理员选项。
    功能:这个视图显示了角色之间的权限继承关系,即哪些角色被授予了其他角色。

DBA_SYS_PRIVS

  • GRANTEE:被授予权限的用户或角色。
  • PRIVILEGE:授予的系统权限。
  • ADMIN_OPTION:指示是否授予了管理员选项。
    功能:这个视图列出了授予用户和角色的系统权限。

ROLE_SYS_PRIVS

  • ROLE:角色名称。
  • PRIVILEGE:授予角色的系统权限。
  • ADMIN_OPTION:指示是否授予了管理员选项。
    功能:这个视图显示了授予角色的系统权限。

ROLE_TAB_PRIVS

  • ROLE:角色名称。
  • OWNER:对象的所有者。
  • TABLE_NAME:表名或视图名。
  • PRIVILEGE:授予的对象权限(如SELECT、INSERT、UPDATE等)。
  • GRANTABLE:指示是否可以将权限授予其他用户。
    功能:这个视图列出了授予角色的对象权限,包括表和视图。

SESSION_ROLES

  • ROLE:当前会话中启用的角色。
    功能:这个视图显示了当前会话中用户启用的角色。这有助于了解用户当前具有哪些角色权限。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

远歌已逝

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值