
# 用户自定义鉴权使用
devspore提供鉴权插件接口，用户只需实现对应鉴权接口即可。
#### 自定义鉴权插件
- 继承抽象类Processor，实现doProcess接口，可定义多个插件。
- 插件均需注册为bean。
  ```
  import com.huawei.devspore.plugin.spi.authorization.AuthObject;
  import com.huawei.devspore.plugin.spi.authorization.AuthSubject;
  import com.huawei.devspore.plugin.spi.authorization.Authorizer;
  import org.springframework.stereotype.Component;
  /**
   * custom Authorizer
   */
  @Component
  public class CustomAuthorizer implements Authorizer {
     /**
       * 执行鉴权
       * 
       * @param subject 鉴权主体
       * @param resource 鉴权客体，被鉴权对象
       * @param operation 被鉴权的动作，传入方法自动注解的operation，为MetaBo对象上的对应的Operation:
       *        CREATE,DELETE,UPDATE,VIEW...或者用户自定义扩展API中的action
       * @param properties 鉴权动作的其它context
       * @return 鉴权通过返回true,否则返回false
       */
      @Override
      public boolean authorize(@NonNull final AuthSubject subject, @NonNull final AuthObject resource,
          @NonNull final String operation, @Nullable final Map<String, String> properties) {
          // do your authorizer code
          ........
          return true;
      }
  }
  ```
  
 
- 配置文件。
  ```
  devspore:
    horizon:
      processors: authorizerProcessor
  ```
  
#### AuthSubject对象
AuthSubject对象即鉴权主体。
表1AuthSubject对象参数说明 
| 参数名称     | 数据类型   | 描述                                                                                                                                                                                                                                                                                                                                                   |
|:---|:---|:---|
| tenantId | String | 根据用户所在的租户传值： - 对于非多租应用（MetaService中tenantModel为空），允许为空。  - 如果为多租应用（MetaService中tenantModel值为TENANT或者TENANT_PROJECT），则传入tenantId。   |
| uid      | String | 鉴权主体的user id，不允许为空。                                                                                                                                                                                                                                                                                                                                  |
   
#### AuthObject对象
AuthObject对象即鉴权客体，被鉴权对象。
表2AuthObject对象参数说明 
| 参数名称      | 数据类型   | 描述                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
|:---|:---|:---|
| projectId | String | 被鉴权资源所在的项目id，对于不属于项目的资源，允许为空。 - 对于非多项目应用（MetaService中tenantModel为null或者TENANT），允许为空。  - 如果为多项目应用（MetaService中tenantModel值为TENANT_PROJECT），则传入projectId。                                                                                          |
| resource  | String | 被鉴权资源，不允许为空。 根据MetaBOAuthorizeType不同的值，传入对应值。 - ROOT：传入BO对象所在的Root BO的id。  - TYPE_LEVEL：传入BO name。  - INSTANCE_LEVEL：传入BO对象id。   |
   
#### horizon插件与鉴权插件配合使用
开启自定义鉴权插件后，devspore为用户自动生成内置[入口插件](https://support.huaweicloud.com/devg-astropro/astropro_06_0016.html#astropro_06_0016__section12333114515405)，并在内置[入口插件](https://support.huaweicloud.com/devg-astropro/astropro_06_0016.html#astropro_06_0016__section12333114515405)中实现向鉴权接口的参数传递；用户只需实现Authorizer.authorize鉴权接口即可。
- 内置[入口插件](https://support.huaweicloud.com/devg-astropro/astropro_06_0016.html#astropro_06_0016__section12333114515405)。
  ```
  package com.huawei.devspore.horizon.authorization;
  import com.huawei.devspore.horizon.DataEvent;
  import com.huawei.devspore.horizon.Operation;
  import com.huawei.devspore.horizon.exception.PluginException;
  import com.huawei.devspore.horizon.factory.Plugins;
  import com.huawei.devspore.horizon.processor.Processor;
  import com.huawei.devspore.metadata.v1.model.MetaBO;
  import com.huawei.devspore.plugin.spi.authentication.UserStore;
  import com.huawei.devspore.plugin.spi.authorization.AuthObject;
  import com.huawei.devspore.plugin.spi.authorization.AuthSubject;
  import com.huawei.devspore.plugin.spi.authorization.Authorizer;
  import org.springframework.beans.factory.annotation.Autowired;
  import org.springframework.lang.NonNull;
  import org.springframework.lang.Nullable;
  import org.springframework.stereotype.Component;
  import java.util.Map;
  @Component
  public class AuthorizerProcessor extends Processor {
      @Autowired(required = false)
      private UserStore userStore;
      @Autowired(required = false)
      private Authorizer authorizer;
      @Override
      public boolean doProcess(@NonNull final DataEvent dataEvent) throws PluginException {
          if (authorizer == null) {
              throw new PluginException("No Authorizer SPI implementation defined");
          }
          MetaBO metaBO = Plugins.getMetaBO(dataEvent);
          AuthObject resource = new AuthObject();
          switch (metaBO.getAtzType()) {
              case TYPE_LEVEL:
                  resource.setResource(metaBO.getName());
                  return authorize(getAuthSubject(), resource, getOperation(dataEvent), null);
              case INSTANCE_LEVEL:
                  resource.setResource(dataEvent.getId().toString());
                  return authorize(getAuthSubject(), resource, getOperation(dataEvent), null);
              default:
                  return true;
          }
      }
      private AuthSubject getAuthSubject() {
          AuthSubject authSubject = new AuthSubject();
          authSubject.setTenantId(userStore.getUserInfo().getTenantId());
          authSubject.setUid(userStore.getUserInfo().getUserId());
          return authSubject;
      }
      /**
       * @return operation for authorization, audit and other purposes
       */
      public String getOperation(DataEvent dataEvent) {
          if (dataEvent.getOperation() == Operation.CUSTOM) {
              return dataEvent.getCustomMethod();
          } else {
              return dataEvent.getOperation().toString();
          }
      }
      /**
       * 执行鉴权
       *
       * @param subject 鉴权主体
       * @param resource 鉴权客体，被鉴权对象
       * @param operation 被鉴权的动作，传入方法自动注解的operation，为aggregate root对象上的对应的Operation:
       *        CREATE,DELETE,UPDATE,VIEW,VIEW_SECRET或者MetaExtAction中的action
       * @param properties 鉴权动作的其它context
       * @return 鉴权通过返回true, 否则返回false
       */
      public boolean authorize(@NonNull final AuthSubject subject, @NonNull final AuthObject resource,
          @NonNull final String operation, @Nullable final Map<String, String> properties) {
          return authorizer.authorize(subject, resource, operation, properties);
      }
  }
  ```
  
- UserStore接口介绍：[UserStore接口介绍](https://support.huaweicloud.com/devg-astropro/astropro_06_0022.html#astropro_06_0022__section1183410133357)。
- UserInfo用户信息类介绍：[UserInfo用户信息类](https://support.huaweicloud.com/devg-astropro/astropro_06_0022.html#astropro_06_0022__section0518162214341)。
若内置[入口插件](https://support.huaweicloud.com/devg-astropro/astropro_06_0016.html#astropro_06_0016__section12333114515405)无法满足用户业务需求，可在自动生成的DefaultRequestPlugin中完成插件逻辑，也可自定义插件，详见[拦截插件](https://support.huaweicloud.com/devg-astropro/astropro_06_0016.html)。
