文档首页 > > API参考> 如何调用API>

认证鉴权

认证鉴权

分享
更新时间:2021/01/26 GMT+08:00

调用接口有如下两种认证方式,您可以选择其中一种进行认证鉴权。

  • Token认证:通过Token认证通用请求。
  • AK/SK认证:通过AK(Access Key ID)/SK(Secret Access Key)加密调用请求。

Token认证

Token的有效期为24小时,需要使用一个Token鉴权时,可以先缓存起来,避免频繁调用。

Token在计算机系统中代表令牌(临时)的意思,拥有Token就代表拥有某种权限。Token认证就是在调用API的时候将Token加到请求消息头,从而通过身份认证,获得操作API的权限。

Token可通过调用获取用户Token接口获取,调用本服务API需要project级别的Token,即调用获取用户Token接口时,请求body中auth.scope的取值需要选择project,如下所示。

{ 
    "auth": { 
        "identity": { 
            "methods": [ 
                "password" 
            ], 
            "password": { 
                "user": { 
                    "name": "username", 
                    "password": "********", 
                    "domain": { 
                        "name": "domainname" 
                    } 
                } 
            } 
        }, 
        "scope": { 
            "project": { 
                "name": "xxxxxxxx" 
            } 
        } 
    } 
}

获取Token后,再调用其他接口时,您需要在请求消息头中添加“X-Auth-Token”,其值即为Token。例如Token值为“ABCDEFJ....”,则调用接口时将“X-Auth-Token: ABCDEFJ....”加到请求消息头即可,如下所示。

GET https://iam.cn-north-1.myhuaweicloud.com/v3/auth/projects 
Content-Type: application/json 
X-Auth-Token: ABCDEFJ....

您还可以通过这个视频教程了解如何使用Token认证:https://bbs.huaweicloud.com/videos/101333

调用接口步骤

当您使用Token认证方式完成认证鉴权时,需要获取用户Token并在调用接口时增加“X-Auth-Token”到业务接口请求消息头中。

本节介绍如何调用接口完成Token认证。

  1. 发送POST请求到如下URL: https://iam.cn-north-1.myhuaweicloud.com/v3/auth/tokens。

    请求头部参数需要增加:Content-Type:application/json, 以保证请求可以被服务正确处理。

    请求体示例如下:

    {
      "auth": {
        "identity": {
          "methods": [
            "password"
          ],
          "password": {
            "user": {
              "name": "username",  //用户名
              "password": "password",  //密码
              "domain": {
                "name": "domainname"  //账户名
              }
            }
          }
        },
        "scope": {
          "project": {
            "name": "cn-north-1"  //图像识别所属区域信息
          }
        }
      }
    }

    上面示例代码中的用户名和账户名获取方法:

    1. 注册并登录管理控制台。
    2. 鼠标移动至页面右上角的用户名,在下拉列表中单击“我的凭证”。查看相应的用户名和账户名,密码为该用户名对应的密码。
    3. “项目名”参见项目列表中的有效项目名,默认为“cn-north-1”

  2. 获取Token。请求响应成功后在响应消息头中包含的“X-Subject-Token”的值即为Token值。
  3. 调用业务接口,在请求消息头中增加“X-Auth-Token”,“X-Auth-Token”的取值为步骤2获取的Token。

示例

  • CURL方式
    1. 创建data.json文件,文件内容如下, 其中需要修改usernamepassworddomainname
      {
          "auth": {
              "identity": {
                  "password": {
                      "user": {
                          "name": "username", 
                          "password": "password", 
                          "domain": {
                              "name": "domainname"
                          }
                      }
                  },
                   "methods": [
                      "password"
                  ]
              }, 
              "scope": {
                  "project": {
                      "name": "cn-north-1"
                  }
              }
          }
      }
    2. 使用如下命令获取Token,将会在当前目录下生成文件header.txt。
      curl -X POST https://iam.myhuaweicloud.com/v3/auth/tokens --header 'content-type: application/json'  -d "@data.json" -D header.txt
    3. 打开文件header.txt,可以看到如下内容,其中X-Subject-Token是获得的token。
      HTTP/1.1 201 Created
      ...
      Transfer-Encoding: chunked
      Connection: keep-alive
      X-Iam-Trace-Id: ed91b739-783X-409e-96cc-74573adf027a
      X-Subject-Token: MIIMkgYJKoZIhvcNAQcCoIIM...
      Strict-Transport-Security: max-age=31536000; includeSubdomains;
      ...
    4. 使用如下命令调用服务(图像标签服务), 其中x-auth-token部分,填写上一步中获取到的token。
      curl -X POST https://image.cn-north-1.myhuaweicloud.com/v1.0/image/tagging \
        --header 'Content-Type: application/json' \
        --header "X-Auth-Token: $TOKEN" -d '
       {
            "image":"",
            "url":"https://ais-sample-data.obs.myhuaweicloud.com/tagging-normal.jpg",
            "language": "zh",
            "limit": 5,
            "threshold": 30.0
      }'
  • java方式
      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
     25
     26
     27
     28
     29
     30
     31
     32
     33
     34
     35
     36
     37
     38
     39
     40
     41
     42
     43
     44
     45
     46
     47
     48
     49
     50
     51
     52
     53
     54
     55
     56
     57
     58
     59
     60
     61
     62
     63
     64
     65
     66
     67
     68
     69
     70
     71
     72
     73
     74
     75
     76
     77
     78
     79
     80
     81
     82
     83
     84
     85
     86
     87
     88
     89
     90
     91
     92
     93
     94
     95
     96
     97
     98
     99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    package com.huawei.ais.demo;
    
    import java.io.File;
    import java.io.IOException;
    import java.net.URISyntaxException;
    
    import com.alibaba.fastjson.JSON;
    import com.alibaba.fastjson.serializer.SerializerFeature;
    import org.apache.commons.codec.binary.Base64;
    import org.apache.commons.io.FileUtils;
    import org.apache.commons.io.IOUtils;
    import org.apache.http.Header;
    import org.apache.http.HttpResponse;
    import org.apache.http.entity.ContentType;
    import org.apache.http.entity.StringEntity;
    import org.apache.http.message.BasicHeader;
    
    import com.alibaba.fastjson.JSONArray;
    import com.alibaba.fastjson.JSONObject;
    import com.huawei.ais.sdk.util.HttpClientUtils;
    
    /**
     * 使用Token认证方式访问服务
     */
    public class TokenDemo {
    	private static final String projectName = "cn-north-1"; // 华北-北京(cn-north-1)的配置
            public static int connectionTimeout = 5000; //连接目标url超时限制参数
    	public static int connectionRequestTimeout = 1000;//连接池获取可用连接超时限制参数
    	public static int socketTimeout =  5000;//获取服务器响应数据超时限制参数
    
    	/**
    	 * 构造使用Token方式访问服务的请求Token对象
    	 * 
    	 * @param username 用户名
    	 * @param passwd 密码
    	 * @param domainName 域名
    	 * @param projectName 项目名称
    	 * @return 构造访问的JSON对象
    	 */
    	private static String requestBody(String username, String passwd, String domainName, String projectName) {
    		JSONObject auth = new JSONObject();
    
    		JSONObject identity = new JSONObject();
    
    		JSONArray methods = new JSONArray();
    		methods.add("password");
    		identity.put("methods", methods);
    
    		JSONObject password = new JSONObject();
    
    		JSONObject user = new JSONObject();
    		user.put("name", username);
    		user.put("password", passwd);
    
    		JSONObject domain = new JSONObject();
    		domain.put("name", domainName);
    		user.put("domain", domain);
    
    		password.put("user", user);
    
    		identity.put("password", password);
    
    		JSONObject scope = new JSONObject();
    
    		JSONObject scopeProject = new JSONObject();
    		scopeProject.put("name", projectName);
    
    		scope.put("project", scopeProject);
    
    		auth.put("identity", identity);
    		auth.put("scope", scope);
    
    		JSONObject params = new JSONObject();
    		params.put("auth", auth);
    		return params.toJSONString();
    	}
    
    	/**
    	 * 获取Token参数,此函数的目的,主要为了从HTTP请求返回体中的Header中提取出Token
    	 * 参数名为: X-Subject-Token
    	 * 
    	 * @param username   用户名
    	 * @param password   密码
    	 * @param projectName 区域名,可以参考http://developer.huaweicloud.com/dev/endpoint
    	 * @return 包含Token串的返回体,
    	 * @throws URISyntaxException
    	 * @throws UnsupportedOperationException
    	 * @throws IOException
    	 */
    	private static String getToken(String username, String password, String projectName)
    			throws URISyntaxException, UnsupportedOperationException, IOException {
    		String requestBody = requestBody(username, password, username, projectName);
    		String url ="https://iam.myhuaweicloud.com/v3/auth/tokens";
    		Header[] headers = new Header[] { new BasicHeader("Content-Type", ContentType.APPLICATION_JSON.toString()) };
    		StringEntity stringEntity = new StringEntity(requestBody,
    				"utf-8");
    
    		HttpResponse response = HttpClientUtils.post(url, headers, stringEntity, connectionTimeout, connectionRequestTimeout, socketTimeout);
    		Header[] xst = response.getHeaders("X-Subject-Token");
    		return xst[0].getValue();
    	}
    
    	/**
    	 * 使用Base64编码后的文件方式,使用Token认证方式访问服务
    	 * @param token token认证串
    	 * @param formFile 文件路径
    	 * @throws IOException
    	 */
    	public static void requestImageTaggingBase64(String token, String formFile) throws IOException {
    		String url = ServiceAccessBuilder.getCurrentEndpoint(projectName)+"/v1.0/image/tagging";
    		Header[] headers = new Header[] {new BasicHeader("X-Auth-Token", token) ,new BasicHeader("Content-Type", "application/json")};
    		String requestBody=toBase64Str(formFile);
    		StringEntity stringEntity = new StringEntity(requestBody, "utf-8");
    		try {
    			HttpResponse response = HttpClientUtils.post(url, headers, stringEntity, connectionTimeout, connectionRequestTimeout, socketTimeout);
    			System.out.println(response);
    			String content = IOUtils.toString(response.getEntity().getContent());
    			System.out.println(JSON.toJSONString(JSON.parse(content.toString()), SerializerFeature.PrettyFormat));
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    	}
    	
    	/**
    	 * 将二进制文件转为经Base64编码之后的请求访问对象(JSON串格式)
    	 * 
    	 * @param file 文件名
    	 * @return 包含被Base64编码之后的文件字符流的JSON对象
    	 * @throws IOException
    	 */
    	public static String toBase64Str(String file) throws IOException{
    		byte[] fileData = FileUtils.readFileToByteArray(new File(file));
    		String fileBase64Str = Base64.encodeBase64String(fileData);
    		JSONObject json = new JSONObject();
    		json.put("image", fileBase64Str);
    		return json.toJSONString();
    	}
    
    	/**
    	 * 调用主入口函数
    	 */
    	public static void main(String[] args) throws URISyntaxException, UnsupportedOperationException, IOException {
    		String username = "zhangshan";    // 此处,请输入用户名
    		String password = "*******";	  // 此处,请输入对应用户名的密码
    
    		String token = getToken(username, password, projectName);
    		System.out.println(token);
    		requestImageTaggingBase64(token, "data/image-tagging-demo-1.jpg");
    	}
    }
    

AK/SK认证

AK/SK签名认证、Token认证方式仅支持消息体大小12M以内的请求使用。

AK/SK认证就是使用AK/SK对请求进行签名,在请求时将签名信息添加到消息头,从而通过身份认证。

  • AK(Access Key ID):访问密钥ID。与私有访问密钥关联的唯一标识符;访问密钥ID和私有访问密钥一起使用,对请求进行加密签名。
  • SK(Secret Access Key):与访问密钥ID结合使用的密钥,对请求进行加密签名,可标识发送方,并防止请求被修改。

使用AK/SK认证时,您可以基于签名算法使用AK/SK对请求进行签名,也可以使用专门的签名SDK对请求进行签名。详细的签名方法和SDK使用方法请参见API签名指南

签名SDK只提供签名功能,与服务提供的SDK不同,使用时请注意。

获取AK/SK

  1. 注册并登录管理控制台。
  2. 鼠标移动至页面右上角的用户名,在下拉列表中单击“我的凭证”。在“我的凭证”界面,单击“管理访问密钥”页签。
  3. 单击“新增访问密钥”,弹出“新增访问密钥”对话框。
  4. 输入当前用户的登录密码,并通过邮箱或者手机进行验证,输入对应的验证码,单击“确定”,下载访问密钥。

    • 在统一身份服务中创建的用户,如果创建时未填写邮箱或者手机号,则只需校验登录密码。
    • 为防止访问密钥泄露,建议您将其保存到安全的位置。

示例代码

下面代码展示了如何对一个请求进行签名,并通过AisAccess发送一个HTTPS请求的过程:

代码分成两个类进行演示:

ResponseProcessUtils:工具类,用于处理结果的返回。

ImageTaggingDemo:进行相关参数ak,sk,region的配置,访问图像标签服务的示例。

  • ResponseProcessUtils.java
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    package com.huawei.ais.demo; 
     
    import java.io.FileOutputStream; 
    import java.io.IOException; 
    import java.nio.ByteBuffer; 
    import java.nio.channels.FileChannel; 
     
    import org.apache.http.HttpResponse; 
     
    import com.alibaba.fastjson.JSON; 
    import com.alibaba.fastjson.JSONObject; 
    import com.cloud.sdk.util.Base64; 
    import com.huawei.ais.sdk.util.HttpClientUtils; 
     
    /** 
     * 访问服务返回结果信息验证的工具类 
     */ 
    public class ResponseProcessUtils { 
         
        /** 
         * 打印出服务访问完成的HTTP状态码  
         *  
         * @param response 响应对象 
         */ 
        public static void processResponseStatus(HttpResponse response) { 
            System.out.println(response.getStatusLine().getStatusCode()); 
        } 
         
        /** 
         * 打印出服务访问完成后,转化为文本的字符流,主要用于JSON数据的展示 
         *  
         * @param response 响应对象 
         * @throws UnsupportedOperationException 
         * @throws IOException 
         */ 
        public static void processResponse(HttpResponse response) throws UnsupportedOperationException, IOException { 
            System.out.println(HttpClientUtils.convertStreamToString(response.getEntity().getContent())); 
        } 
         
        /** 
         * 处理返回Base64编码的图像文件的生成 
         *  
         * @param response 
         * @throws UnsupportedOperationException 
         * @throws IOException 
         */ 
        public static void processResponseWithImage(HttpResponse response, String fileName) throws UnsupportedOperationException, IOException { 
            String result = HttpClientUtils.convertStreamToString(response.getEntity().getContent()); 
            JSONObject resp = JSON.parseObject(result); 
            String imageString = (String)resp.get("result"); 
            byte[] fileBytes = Base64.decode(imageString); 
            writeBytesToFile(fileName, fileBytes); 
        } 
         
        /** 
         *  将字节数组写入到文件, 用于支持二进制文件(如图片)的生成 
         * @param fileName 文件名 
         * @param data 数据 
         * @throws IOException 
         */ 
        public static void writeBytesToFile(String fileName, byte[] data) throws IOException{ 
     
            FileChannel fc = null; 
            try { 
                ByteBuffer bb = ByteBuffer.wrap(data); 
                fc = new FileOutputStream(fileName).getChannel(); 
                fc.write(bb); 
                 
            } catch (Exception e) { 
                e.printStackTrace(); 
                System.out.println(e.getMessage()); 
            } 
            finally { 
                fc.close(); 
            } 
        } 
    }
    
  • ImageTaggingDemo.java
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    package com.huawei.ais.demo.image;
    
    import com.alibaba.fastjson.JSON;
    import com.alibaba.fastjson.JSONObject;
    import com.alibaba.fastjson.serializer.SerializerFeature;
    import com.huawei.ais.demo.ResponseProcessUtils;
    import com.huawei.ais.demo.ServiceAccessBuilder;
    import com.huawei.ais.sdk.AisAccess;
    import com.huawei.ais.sdk.util.HttpClientUtils;
    
    import org.apache.commons.codec.binary.Base64;
    import org.apache.commons.io.FileUtils;
    import org.apache.http.HttpResponse;
    import org.apache.http.entity.StringEntity;
    
    
    import java.io.File;
    import java.io.IOException;
    
    
    /**
     *  图片标签服务的使用示例类
     */
    public class ImageTaggingDemo {
    	//
    	// 图片标签服务的使用示例函数
    	//
    	private static void imageTaggingDemo() throws IOException {
    
    		// 1. 图片标签服务的的基本信息,生成对应的一个客户端连接对象
    
    		AisAccess service = ServiceAccessBuilder.builder()				
                           .ak("######")                       // your ak
                           .sk("######")                       // your sk
                           .region("cn-north-1")               // 图像识别服务华北-北京一的配置
                           .connectionTimeout(5000)            // 连接目标url超时限制
                           .connectionRequestTimeout(1000)     // 连接池获取可用连接超时限制		
                           .socketTimeout(20000)               // 获取服务器响应数据超时限制
                           .build();
    
    		try {
    			//
    			// 2.构建访问图片标签服务需要的参数
    			//
    			String uri = "/v1.0/image/tagging";
    			byte[] fileData = FileUtils.readFileToByteArray(new File("data/image-tagging-demo-1.jpg"));
    			String fileBase64Str = Base64.encodeBase64String(fileData);
    			
    			JSONObject json = new JSONObject();
    			json.put("image", fileBase64Str);
    			json.put("threshold", 60);
    			StringEntity stringEntity = new StringEntity(json.toJSONString(), "utf-8");
    			
    			// 3.传入图片标签服务对应的uri参数, 传入图片标签服务需要的参数,
    			// 该参数主要通过JSON对象的方式传入, 使用POST方法调用服务
    			HttpResponse response = service.post(uri, stringEntity);
    			
    			// 4.验证服务调用返回的状态是否成功,如果为200, 为成功, 否则失败。
    			ResponseProcessUtils.processResponseStatus(response);
    			
    			// 5.处理服务返回的字符流,输出识别结果。
    			JSONObject jsonObject = JSON.parseObject(HttpClientUtils.convertStreamToString(response.getEntity().getContent()));
    			System.out.println(JSON.toJSONString(JSON.parse(jsonObject.toString()), SerializerFeature.PrettyFormat));
    		} catch (Exception e) {
    			e.printStackTrace();
    		} finally {
    
    			// 6.使用完毕,关闭服务的客户端连接
    			service.close();
    		}
    	}
    
    	//
    	// 主入口函数
    	//
    	public static void main(String[] args) throws IOException {
    		// 测试入口函数
    		imageTaggingDemo();
    	}
    }
    
分享:

    相关文档

    相关产品

文档是否有解决您的问题?

提交成功!非常感谢您的反馈,我们会继续努力做到更好!
反馈提交失败,请稍后再试!

*必选

请至少选择或填写一项反馈信息

字符长度不能超过200

提交反馈 取消

如您有其它疑问,您也可以通过华为云社区问答频道来与我们联系探讨

智能客服提问云社区提问