springsecurity----rbac权限控制模型,和权限相关知识点整理(代码片段)

大忽悠爱忽悠 大忽悠爱忽悠     2023-02-06     473

关键词:


我们开发一个系统,必然面临权限控制的问题,即不同的用户具有不同的访问、操作、数据权限。形成理论的权限控制模型有:自主访问控制(DAC: Discretionary Access Control)、强制访问控制(MAC: Mandatory Access Control)、基于属性的权限验证(ABAC: Attribute-Based Access Control)等。最常被开发者使用也是相对易用、通用的就是RBAC权限模型(Role-Based Access Control),本文就将向大家介绍该权限模型。

RBAC权限模型简介

RBAC权限模型(Role-Based Access Control)即:基于角色的权限控制。模型中有几个关键的术语:

  • 用户:系统接口及功能访问的操作者
  • 权限:能够访问某接口或者做某操作的授权资格
  • 角色:具有一类相同操作权限的用户的总称

RBAC权限模型核心授权逻辑如下:

  • 某用户是什么角色?
  • 某角色具有什么权限?
  • 通过角色的权限推导用户的权限

RBAC的演化进程

用户与权限直接关联


想到权限控制,人们最先想到的一定是用户与权限直接关联的模式,简单地说就是:某个用户具有某些权限。如图:

  • 张三具有创建用户和删除用户的权限,所以他可能系统维护人员
  • 李四具有产品记录管理和销售记录管理权限,所以他可能是一个业务销售人员

这种模型能够清晰的表达用户与权限之间的关系,足够简单。但同时也存在问题:

  • 现在用户是张三、李四,以后随着人员增加,每一个用户都需要重新授权
  • 或者张三、李四离职,需要针对每一个用户进行多种权限的回收

一个用户拥有一个角色

在实际的团体业务中,都可以将用户分类。比如对于薪水管理系统,通常按照级别分类:经理、高级工程师、中级工程师、初级工程师。也就是按照一定的角色分类,通常具有同一角色的用户具有相同的权限。这样改变之后,就可以将针对用户赋权转换为针对角色赋权。因为角色少、权限多,所以基于角色管理权限,减少用户在授权与权限回收过程中的过多操作。

  • 一个用户有一个角色
  • 一个角色有多个操作(菜单)权限
  • 一个操作权限可以赋予多个角色

我们可以用下图中的数据库设计模型,描述这样的关系。


一个用户一个或多个角色

但是在实际的应用系统中,一个用户一个角色远远满足不了需求。如果我们希望一个用户既担任销售角色、又暂时担任副总角色。该怎么做呢?为了增加系统设计的适用性,我们通常设计:

  • 一个用户有一个或多个角色
  • 一个角色包含多个用户
  • 一个角色有多种权限
  • 一个权限可以赋予多个角色

我们可以用下图中的数据库设计模型,描述这样的关系。

  • sys_user是用户信息表,用于存储用户的基本信息,如:用户名、密码
  • sys_role是角色信息表,用于存储系统内所有的角色
  • sys_menu是系统的菜单信息表,用于存储系统内所有的菜单。用id与父id的字段关系维护一个菜单树形结构。
  • sys_user_role是用户角色多对多关系表,一条userid与roleid的关系记录表示该用户具有该角色,该角色包含该用户。
  • sys_role_menu是角色菜单(权限)关系表,一条roleid与menuid的关系记录表示该角色由某菜单权限,该菜单权限可以被某角色访问。

页面访问权限与操作权限

  • 页面访问权限:
    所有系统都是由一个个的页面组成,页面再组成模块,用户是否能看到这个页面的菜单、是否能进入这个页面就称为页面访问权限。
  • 操作权限:
    用户在操作系统中的任何动作、交互都需要有操作权限,如增删改查等。比如:某个按钮,某个超链接用户是否可以点击,是否应该看见的权限。


为了适应这种需求,我们可以把页面资源(菜单)和操作资源(按钮)分表存放,如上图。也可以把二者放到一个表里面存放,用一个字段进行标志区分。


数据权限

数据权限比较好理解,就是某个用户能够访问和操作哪些数据。

  • 通常来说,数据权限由用户所属的组织来确定。比如:生产一部只能看自己部门的生产数据,生产二部只能看自己部门的生产数据;销售部门只能看销售数据,不能看财务部门的数据。而公司的总经理可以看所有的数据。
  • 在实际的业务系统中,数据权限往往更加复杂。非常有可能销售部门可以看生产部门的数据,以确定销售策略、安排计划等。

所以为了面对复杂的需求,数据权限的控制通常是由程序员书写个性化的SQL来限制数据范围的,而不是交给权限模型或者Spring Security或shiro来控制。当然也可以从权限模型或者权限框架的角度去解决这个问题,但适用性有限。


动态加载用户角色权限数据

我们所有的用户、角色、权限信息都是在配置文件里面写死的,然而在实际的业务系统中,这些信息通常是存放在RBAC权限模型的数据库表中的。

下面来把这些信息从数据库里面进行加载。


下面我们来回顾一下其中的核心概念:

  • RBAC的权限模型可以从用户获取为用户分配的一个或多个角色,从用户的角色又可以获取该角色的多种权限。通过关联查询可以获取某个用户的角色信息和权限信息
  • 如果我们不希望用户、角色、权限信息写死在配置里面。我们应该实现UserDetails与UserDetailsService接口,从而从数据库或者其他的存储上动态的加载这些信息。


UserDetails与UserDetailsService接口

UserDetails接口表达你是谁?你有什么角色权限。UserDetailsService接口表达的是如何动态加载UserDetails数据。

  • UserDetailsService接口有一个方法叫做loadUserByUsername,我们实现动态加载用户、角色、权限信息就是通过实现该方法。函数见名知义:通过用户名加载用户。该方法的返回值就是UserDetails
  • UserDetails就是用户信息,即:用户名、密码、该用户所具有的权限。

下面我们来看一下UserDetails接口都有哪些方法。

public interface UserDetails extends Serializable 
    //获取用户的权限集合
    Collection<? extends GrantedAuthority> getAuthorities();

    //获取密码
    String getPassword();

    //获取用户名
    String getUsername();

    //账号是否没过期
    boolean isAccountNonExpired();

    //账号是否没被锁定
    boolean isAccountNonLocked();

    //密码是否没过期
    boolean isCredentialsNonExpired();

    //账户是否可用
    boolean isEnabled();

现在我们明白了,只要我们把这些信息提供给Spring Security,Spring Security就知道怎么做登录验证了,根本不需要我们自己写Controller实现登录验证逻辑。那我们怎么把这些信息提供给Spring Security,用的就是下面的接口方法

public interface UserDetailsService 
   UserDetails loadUserByUsername(String username) throws UsernameNotFoundException;


实现UserDetails 接口

public class MyUserDetails implements UserDetails 

  String password;  //密码
  String username;  //用户名
  boolean accountNonExpired;   //是否没过期
  boolean accountNonLocked;   //是否没被锁定
  boolean credentialsNonExpired;  //密码是否没过期
  boolean enabled;  //账号是否可用
  Collection<? extends GrantedAuthority> authorities;  //用户的权限集合


  public void setPassword(String password) 
    this.password = password;
  

  public void setUsername(String username) 
    this.username = username;
  

  public void setAccountNonExpired(boolean accountNonExpired) 
    this.accountNonExpired = accountNonExpired;
  

  public void setAccountNonLocked(boolean accountNonLocked) 
    this.accountNonLocked = accountNonLocked;
  

  public void setCredentialsNonExpired(boolean credentialsNonExpired) 
    this.credentialsNonExpired = credentialsNonExpired;
  

  public void setEnabled(boolean enabled) 
    this.enabled = enabled;
  

  public void setAuthorities(Collection<? extends GrantedAuthority> authorities) 
    this.authorities = authorities;
  

  @Override
  public Collection<? extends GrantedAuthority> getAuthorities() 
    return authorities;
  

  @Override
  public String getPassword() 
    return password;
  

  @Override
  public String getUsername() 
    return username;
  

  @Override
  public boolean isAccountNonExpired() 
    return true;   //暂时未用到,直接返回true,表示账户未过期
  

  @Override
  public boolean isAccountNonLocked() 
    return true;   //暂时未用到,直接返回true,表示账户未被锁定
  

  @Override
  public boolean isCredentialsNonExpired() 
    return true;   //暂时未用到,直接返回true,表示账户密码未过期
  

  @Override
  public boolean isEnabled() 
    return enabled;
  

我们就是写了一个适应于UserDetails的java POJO类,所谓的 UserDetails接口实现就是一些get方法。

  • get方法由Spring Security调用,获取认证及鉴权的数据
  • 我们通过set方法或构造函数为 Spring Security提供UserDetails数据(从数据库查询)。
  • 当enabled的值为false的时候,Spring Security会自动的禁用该用户,禁止该用户进行系统登录。
  • 通常数据库表sys_user字段要和MyUserDetails 属性一一对应,比如username、password、enabled。

目前数据库表里面没有定义accountNonExpired、accountNonLocked、credentialsNonExpired这三个字段,目前暂时也用不到,因此这三个属性对应的get方法,返回值默认为true


实现UserDetailsService接口

@Component
public class MyUserDetailsService implements UserDetailsService 

    @Resource
    private MyUserDetailsServiceMapper myUserDetailsServiceMapper;

    @Override
    public UserDetails loadUserByUsername(String username)
            throws UsernameNotFoundException 

        //获得用户信息
        MyUserDetails myUserDetails =
                myUserDetailsServiceMapper.findByUserName(username);

        if(myUserDetails == null)
            throw new UsernameNotFoundException("用户名不存在");
        

        //获得用户角色列表
        List<String> roleCodes =
                myUserDetailsServiceMapper.findRoleByUserName(username);

        //通过角色列表获取权限列表
        List<String> authorities =
                myUserDetailsServiceMapper.findAuthorityByRoleCodes(roleCodes);

        //为角色标识加上ROLE_前缀(Spring Security规范)
        roleCodes = roleCodes.stream()
                .map(rc -> "ROLE_" + rc )
                .collect(Collectors.toList());

        //角色是一种特殊的权限,所以合并
        authorities.addAll(roleCodes);
        //转成用逗号分隔的字符串,为用户设置权限标识
        myUserDetails.setAuthorities(
        
                AuthorityUtils.commaSeparatedStringToAuthorityList(
                    String.join(",",authorities)
                )
        );


        return myUserDetails;
    


  • 角色是一种特殊的权限,在Spring Security我们可以使用hasRole(角色标识)表达式判断用户是否具有某个角色,决定他是否可以做某个操作;通过hasAuthority(权限标识)表达式判断是否具有某个操作权限。
  • 上述实现中用到的MyUserDetailsServiceMapper 是Mybatis操作数据库的接口实现,看文末代码。

注册UserDetailsService

重写WebSecurityConfigurerAdapter的 configure(AuthenticationManagerBuilder auth)方法

@Bean("passwordEncoder")
public PasswordEncoder passwordEncoder()
    return new BCryptPasswordEncoder();


@Resource
private MyUserDetailsService userDetailsService;

@Override
protected void configure(AuthenticationManagerBuilder builder) throws Exception 
    builder.userDetailsService(userDetailsService)
            .passwordEncoder(passwordEncoder());

使用BCryptPasswordEncoder,表示存储中(数据库)取出的密码必须是经过BCrypt加密算法加密的。

这里需要注意的是,因为我们使用了BCryptPasswordEncoder加密解密,所以数据库表里面存的密码应该是加密之后的密码(造数据的过程),可以使用如下代码加密(如密码是:123456)。将打印结果保存保存到密码字段。

@Resource
PasswordEncoder passwordEncoder;

@Test
public void contextLoads() 
    System.out.println(passwordEncoder.encode("123456"));


总结

至此,我们将系统里面的所有的用户、角色、权限信息都通过UserDetailsService和UserDetails告知了Spring Security。但是多数朋友可能仍然不知道该怎样实现登录的功能,其实剩下的事情很简单了:

  • 写一个登录界面,写一个登录表单,表单使用post方法提交到默认的/login路径
  • 表单的用户名、密码字段名称默认是username、password。
  • 写一个登录成功之后的跳转页面,比如index.html

然后把这些信息通过配置方式告知Spring Security ,以上的配置信息名称都可以灵活修改。


附录:Mybatis持久层数据接口

public interface MyUserDetailsServiceMapper 

    //根据userID查询用户信息
    @Select("SELECT username,password,enabled\\n" +
            "FROM sys_user u\\n" +
            "WHERE u.username = #userId")
    MyUserDetails findByUserName(@Param("userId") String userId);

    //根据userID查询用户角色
    @Select("SELECT role_code\\n" +
            "FROM sys_role r\\n" +
            "LEFT JOIN sys_user_role ur ON r.id = ur.role_id\\n" +
            "LEFT JOIN sys_user u ON u.id = ur.user_id\\n" +
            "WHERE u.username = #userId")
    List<String> findRoleByUserName(@Param("userId") String userId);


    //根据用户角色查询用户权限
    @Select(
      "<script>",
         "SELECT url " ,
         "FROM sys_menu m " ,
         "LEFT JOIN sys_role_menu rm ON m.id = rm.menu_id " ,
         "LEFT JOIN sys_role r ON r.id = rm.role_id ",
         "WHERE r.role_code IN ",
         "<foreach collection='roleCodes' item='roleCode' open='(' separator=',' close=')'>",
            "#roleCode",
         "</foreach>",
      "</script>"
    )
    List<String> findAuthorityByRoleCodes(@Param("roleCodes") List<String> roleCodes);



动态加载资源鉴权规则

我们已经实现了从RBAC数据库中加载用户的角色、权限信息。在我们的Spring Security配置类SecurityConfig中仍然有一部分内容是通过代码静态配置的,那就是:资源鉴权规则。

简单说“资源鉴权规则”就是:你有哪些权限?这些权限能够访问哪些资源?即:权限与资源的匹配关系。

实现效果

上图是资源鉴权规则完成之后的效果:

  • 首先将静态规则去掉(注释掉的部分内容),这部分内容我们将替换为动态从数据库加载
  • 登录页面“login.html”和登录认证处理路径“/login”需完全对外开发,不需任何鉴权就可以访问
  • 首页"/index"必须authenticated,即:登陆之后才能访问。不做其他额外鉴权规则控制。
  • 最后,其他的资源的访问我们通过权限规则表达式实现,表达式规则中使用了rbacService,这个类我们自定义实现。该类服务hasPermission从内存(或数据库)动态加载资源匹配规则,进行资源访问鉴权。

动态资源鉴权规则

@Component("rbacService")
public class MyRBACService 

    /**
     * 判断某用户是否具有该request资源的访问权限
     */
    public boolean hasPermission(HttpServletRequest request, Authentication authentication)

//获取认证主体
        Object principal = authentication.getPrincipal();

        if(principal instanceof UserDetails)
            //获取当前登录用户的UserDetails
            UserDetails userDetails = ((UserDetails)principal);

            //将当前请求的访问资源路径,如:"/syslog",包装成资源权限标识
            SimpleGrantedAuthority simpleGrantedAuthority
                    = new SimpleGrantedAuthority(request.getRequestURI());
            //判断用户已授权访问的资源中,是否包含“本次请求的资源”
            return userDetails.getAuthorities().contains(simpleGrantedAuthority);
        
        return false;
    

上述代码逻辑很简单:

  • 首先从authentication中获取principal (即UserDetails),UserDetails里面包含authorities(即当前登录用户可以访问的所有的资源访问路径、资源唯一标识)
  • 如果authorities列表中任何一个元素,能够和request.getRequestURI()请求资源路径相匹配,则表示该用户具有访问该资源的权限。
  • hasPermission有两个参数,第一个参数是HttpServletRequest ,第二个参数是Authentication认证主体
  • 用户每一次访问系统资源的时候,都会执行这个方法,判断该用户是否具有访问该资源的权限。

测试一下

如果使用admin用户登录,其加载数据内容如下图(根据之前章节调整RBAC模型数据库表里面的数据)。所以通过admin登录只能访问“用户管理”和“日志管理”功能。

如果使用admin用户登录,其加载数据内容如下图(根据之前章节调整RBAC模型数据库表里面的数据)。所以通过admin登录只能访问“具体业务一”和“具体业务二”功能。


权限表达式使用方法总结

SPEL表达式权限控制

spring security 3.0开始已经可以使用spring Expression表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。Spring Security可用表达式对象的基类是SecurityExpressionRoot

表达式函数描述
hasRole([role])用户拥有指定的角色时返回true (Spring security默认会带有ROLE_前缀),去除前缀参考Remove the ROLE_
hasAnyRole([role1,role2])用户拥有任意一个指定的角色时返回true
hasAuthority([authority])拥有某资源的访问权限时返回true
hasAnyAuthority([auth1,auth2])拥有某些资源其中部分资源的访问权限时返回true
permitAll永远返回true
denyAll永远返回false
anonymous当前用户是anonymous时返回true
rememberMe当前用户是rememberMe用户返回true
authentication当前登录用户的authentication对象
fullAuthenticated当前用户既不是anonymous也不是rememberMe用户时返回true
hasIpAddress(‘192.168.1.0/24’)请求发送的IP匹配时返回true

部分朋友可能会对Authority和Role有些混淆。Authority作为资源访问权限可大可小,可以是某按钮的访问权限(如资源ID:biz1),也可以是某类用户角色的访问权限(如资源ID:ADMIN)。当Authority作为角色资源权限时,hasAuthority(‘ROLE_ADMIN’)与hasRole(‘ADMIN’)是一样的效果


SPEL在全局配置中的使用

我们可以通过继承WebSecurityConfigurerAdapter,实现相关的配置方法,进行全局的安全配置 。下面就为大家介绍一些如何在全局配置中使用SPEL表达式。

URL安全表达式

config.antMatchers("/person/*").access("hasRole('admin') or hasAuthority('ROLE_user')")
      .anyRequest().authenticated();

这里我们定义了应用/person/*URL的范围,只有拥有ADMIN或者USER权限的用户才能访问这些person资源。

安全表达式中引用bean

这种方式,比较适合有复杂权限验证逻辑的情况,当Spring Security提供的默认表达式方法无法满足我们的需求的时候。实际上在上面的动态加载资源鉴权规则里面,我么已经使用了这种方法。首先我们定义一个权限验证的RbacService。

@Component("rbacService")
@Slf4j
public class RbacService 
    //返回true表示验证通过
    public boolean hasPermission(HttpServletRequest request, Authentication authentication) 
        //验证逻辑代码
        return true;
    
    public boolean checkUserId(Authentication authentication, int id) 
        //验证逻辑代码
        return true;
    

对于"/person/id"对应的资源的访问,调用rbacService的bean的方法checkUserId进行权限验证,传递参数为authentication对象和person的id。该id为PathVariable,以#开头表示。

config.antMatchers("/person/id").access("@rbacService.checkUserId(authentication,#id)")
      .anyRequest().access("@rbacService.hasPermission(request,authentication)");

Method表达式安全控制

如果我们想实现方法级别的安全配置,Spring Security提供了四种注解,分别是@PreAuthorize , @PreFilter , @PostAuthorize@PostFilter

开启方法级别注解的配置

在Spring安全配置代码中,加上EnableGlobalMethodSecurity注解,开启方法级别安全配置功能。

@EnableGlobalMethodSecurity(prePostEnabled = true)
public class MySecurityConfig extends WebSecurityConfigurerAdapter 

@EnableGlobalMethodSecurity是一个组合注解,里面包含了@Configuration,所以不需要再加一个@Configuration注解了


使用PreAuthorize注解

@PreAuthorize 注解适合进入方法前的权限验证。只有拥有ADMIN角色才能访问findAll方法。

@PreAuthorize("hasRole('admin')")
public List<PersonDemo> findAll()
    return null;

如果当前登录用户没有PreAuthorize需要的权限,将抛出org.springframework.security.access.AccessDeniedException异常!


使用PostAuthorize注解

@PostAuthorize 在方法执行后再进行权限验证,适合根据返回值结果进行权限验证。Spring EL 提供返回对象能够在表达式语言中获取返回的对象returnObject。下文代码只有返回值的name等于authentication对象的name(当前登录用户名)才能正确返回,否则抛出异常。

@PostAuthorize("returnObject.name == authentication.name")
public PersonDemo findOne()
    String authName =
            SecurityContextHolder.getContext().getAuthentication()查看详情  

web远程控制

...远程控制,还可支持代理局域网端口。支持个人、企业、权限控制。主要功能有以下:基于WEB直接发起远程控制。被控制的PC无需公网也能够控制。远控控制协议支持VNC、RDP、SSH。能够代理局域网端口到公网。支持远控控制录像... 查看详情

microsoftsqlserver无法访问,请检查访问权限

SOS!今天更换电源时中控电脑关机再启动以后就无法打开了,求高手指点,解决以后秒采用参考技术A点击“开始”——“运行”——键入reset_wincc.vbs运行 参考技术B数据库的访问权限不对 查看详情

ad主辅域控切换-辅域控制器升级为主域控制器-详细操作(代码片段)

...更改”点击“是”注册架构主机组件dc2上操作,要管理员权限,最好登录域管账户administrator如果报错误代码0x80040201DllRegisterServer启动失败,可能是权限问题,换为域管administrator登录DC2,在进行操作即可,或者可以试试到system32... 查看详情

ad域安全攻防实践(附攻防矩阵图)

...础上自成一套技术体系,将AD域攻防分为信息收集、权限提升、凭证窃取、横向移动、权限维持等攻击阶段,把域环境下众多且繁杂的攻击行为映射到ATT&CK,梳理成一个AD域攻防矩阵图。(1)域内信息收集... 查看详情

UIActivityIndi​​catorView 不工作(获取影响 UIActivityIndi​​catorView 的 Facebook 权限)

...catorView不工作(获取影响UIActivityIndi​​catorView的Facebook权限)【英文标题】:UIActivityIndicatorViewisnotworking(gettingFacebookpermissionsaffectingUIActivityIndicatorView)【发布时间】:2011-08-0114:40:44【问题描述】:我有一个带有三个选项卡/视图... 查看详情

云控系统都支持哪些安卓手机装机步骤

...拉,锁定AI助手,全部清理。打开手机管家,权限管理-应用权限,除了悬浮窗和定位不开其他全开。允许后台运行。(快手一样),AI助手全部允许。打开设置-显示和亮度-1分钟调至30分钟,通知和状态... 查看详情

风控系统

贷前风控贷前风控是贷款风控体系的起点,是整个风控体系的关键环节,是决定风控效果的核心所在。贷前风控流程一般为用户申请进件-预审批-审批。预审批阶段由系统完成。审批阶段可以通过评分卡、风控模型以及人工审批... 查看详情

内网群控教程

1,外网群控简洁高效,跨网段、跨城市、跨国,(⊙﹏⊙)呃,只要能上网什么都跨,通常没有理由使用内网群控。(开源矿工自2.8始已全面支持外网群控,下载地址)2,因为不知名的原因,或许是爱好^_^,有的矿友喜欢用内网... 查看详情

磁盘备份和还原

...系统,分为两个区即可,做好相关域控搭建、用户、文件权限设置,完成所有安装后进行备份;2.使用U盘进入PE系统,使用工具ghost11.5进行备份;3.打开工具后, 查看详情

权限列表无replicatingdirectorychangesinfilteredset权限项?

1、点“还原默认值”后权限项目的用户或组减少到只有DomainAdmins组、system、AuthenticatedUsers三个了(如图所示)。2、权限列表中不只有“replicatingdirectorychangesinfilteredset”权限选项丢失了,还有很多的其它选项也消失了。但其它消... 查看详情

dc域控服务器与辅助dc域控服务器之间的数据同步

本篇主要是处理DC域控服务器与辅助DC域控服务器之间的数据同步关系,DC域控服务器与辅助DC域控服务器的创建可以参考上篇文章验证DC域控服务器与辅助DC域控服务器之间的数据同步关系,分别在辅助DC域控服务器DC上面新建一... 查看详情

sentinel流控规则简介与实践

...及安装,接下来我们开始介绍Sentinel中的第一个规则,流控规则。文章目录什么是流量控制流量控制设计理念对流控规则整体认识阈值类型QPS案例线程数案例流控模式直接关联案例链路案例流控效果快速失败Warmup案例排队等待 查看详情

企业邮箱有什么功能好用?

...易推出的功能,企业网盘2.0支持管理员按部门分配文件夹权限,当部门人员变更时,权限也会同步变更,不需要管理员再耗费时间精力分配相关权限。还新增了“转移文件(夹)”的功能,管理员只需要设置好权限就可以实现对... 查看详情

《内网安全攻防:渗透测试实战指南》读书笔记:权限维持分析及防御(代码片段)

...ishang下的WebShell2、Weevely3、webacoo4、meterpreter三、域控制器权限持久化1、DSRM后门(1)方法(2)防范2、SSP维持域控权限ÿ 查看详情

《内网安全攻防:渗透测试实战指南》读书笔记:权限维持分析及防御(代码片段)

...ishang下的WebShell2、Weevely3、webacoo4、meterpreter三、域控制器权限持久化1、DSRM后门(1)方法(2)防范2、SSP维持域控权限ÿ 查看详情

共享电脑里面的文件可以删除,不能上传文件

...术A私人创建的文件夹可以上传文件,如果不能上传就是权限方面的设置问题如果是别人的共享出来的文件夹不能上传文件,可能会是对方对文件夹设置了权限 参考技术B1.我的方法是把‎共享权限里原‎来的Ever‎yone用... 查看详情

互联网风控系统架构分析(代码片段)

本文简单介绍风控具体是做什么的,以及一些常见的风控系统实现的架构。文章目录前言一、互联网风控是做什么的?风控的定义二、常见风控系统的实现架构1.风控系统的架构2.风控的系统流程三、核心风险识别环节1.... 查看详情