Authentication

Requests for calling an API can be authenticated using either of the following methods:

  • Token-based authentication: Requests are authenticated using a token.
  • AK/SK-based authentication: Requests are authenticated by encrypting the request body using an AK/SK pair.

Token-based Authentication

The validity period of a token is 24 hours. When using a token for authentication, cache it to prevent frequently calling the IAM API used to obtain a user token.

A token specifies temporary permissions in a computer system. During API authentication using a token, the token is added to requests to get permissions for calling the API.

When calling the API to obtain a user token, you must set auth.scope in the request body to project.

{ 
    "auth": { 
        "identity": { 
            "methods": [ 
                "password" 
            ], 
            "password": { 
                "user": { 
                    "name": "username", 
                    "password": "********",  //The password is that of the current account. If you log in using a subaccount, set this parameter to the password of the subaccount.
                    "domain": { 
                        "name": "domainname" 
                    } 
                } 
            } 
        }, 
        "scope": { 
            "project": { 
                "name": "xxxxxxxx" 
            } 
        } 
    } 
}

After a token is obtained, the X-Auth-Token header field must be added to requests to specify the token when calling other APIs. For example, if the token is ABCDEFJ...., X-Auth-Token: ABCDEFJ.... can be added to a request as follows:

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

Procedure

To use token-based authentication, obtain the user token, and add X-Auth-Token to the request header of the service API when making an API call.

This section describes how to make an API call using token-based authentication.

  1. Send a POST request to https://iam.cn-north-1.myhuaweicloud.com/v3/auth/tokens.

    Add parameter Content-Type: application/json to the request headers to ensure that the service can correctly process the request.

    A sample request body is as follows:

    {
      "auth": {
        "identity": {
          "methods": [
            "password"
          ],
          "password": {
            "user": {
              "name": "username",  //Username
              "password": "password",  //The password is that of the current account. If you log in using a subaccount, set this parameter to the password of the subaccount.
              "domain": {
                "name": "domainname"  //Account name
              }
            }
          }
        },
        "scope": {
          "project": {
            "name": "cn-north-1" //Region of Image Recognition
          }
        }
      }
    }

    To obtain the username and account name in the preceding sample code, do as follows:

    1. Log in to the management console after registration.
    2. Hover the cursor on the username and choose My Credentials from the drop-down list. Check the username and account. The password is the one corresponding to the username.
    3. For project, see the name of the valid project in the project list. The default project is cn-north-1.

  2. Obtain the token. The token value is the X-Subject-Token value in the response header.
  3. To call a service API, add the X-Auth-Token header to the request and set its value to the token obtained in Step 2.

Example

  • cURL
    1. Create the data.json file. The following shows the content of the file, in which you need to change username, password, and domainname as required.
      {
          "auth": {
              "identity": {
                  "password": {
                      "user": {
                          "name": "username", 
                          "password": "password", 
                          "domain": {
                              "name": "domainname"
                          }
                      }
                  },
                   "methods": [
                      "password"
                  ]
              }, 
              "scope": {
                  "project": {
                      "name": "cn-north-1"
                  }
              }
          }
      }
    2. Run the following command to obtain the token. The header.txt file is created in the current directory.
      curl -X POST https://iam.myhuaweicloud.com/v3/auth/tokens --header 'content-type: application/json'  -d "@data.json" -D header.txt
    3. Open the header.txt file. The following information is displayed. The value of X-Subject-Token is the obtained 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. Run the following command to call the service, for example, Image Tagging. Set x-auth-token to the token obtained in the previous step.
      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;
    
    /**
     * Access the service using token-based authentication.
     */
    public class TokenDemo {
    	private static final String projectName = "cn-north-1"; //Configuration of the CN North-Beijing1 region
    	public static int connectionTimeout = 5000; //Timeout limit for connecting to the target URL
    	public static int connectionRequestTimeout = 1000;//Timeout limit for obtaining available connections from the connection pool
    	public static int socketTimeout =  5000;//Timeout limit for obtaining a server response
    
    	/**
    	 * Construct a token request object for accessing the service using token-based authentication.
    	 * 
     * @param username Username
     * @param passwd Password
     * @param domainName Domain name
     * @param projectName Project name
     * @return Construct the JSON object of the access.
    	 */
    	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();
    	}
    
    	/**
     * Obtain the token parameter. Note that this function aims to extract the token from the header in the HTTP response body.
     * The parameter name is X-Subject-Token.
    	 * 
    	 * @param username   Username
     * @param password   Password
     * @param projectName Region name. For details, see https://developer.huaweicloud.com/en-us/endpoint.
     * @return Response body containing the token string
    	 * @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();
    	}
    
    	/**
     * Use the file encoded by Base64 to access the service using token-based authentication.
     * @param token Token-based authentication string
     * @param formFile File path
    	 * @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();
    		}
    	}
    	
    	/**
     * Object (JSON string) to be accessed whose binary file is encoded by Base64.
    	 * 
     * @param file File name
     * @return Contain the JSON object in file character stream after Base64 encoding.
    	 * @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();
    	}
    
    	/**
     * Invoke the main entrypoint function.
    	 */
    	public static void main(String[] args) throws URISyntaxException, UnsupportedOperationException, IOException {
    		String username = "zhangshan";    // Enter the username.
    		String password = "*******";	  // Enter the password.	
    
    		String token = getToken(username, password, projectName);
    		System.out.println(token);
    		requestImageTaggingBase64(token, "data/image-tagging-demo-1.jpg");
    	}
    }
    

AK/SK-based Authentication

AK/SK-based authentication and token-based authentication apply only to requests whose body size is less than 12 MB.

In AK/SK-based authentication, AK/SK is used to sign requests and the signature is then added to the requests for authentication.

  • AK: access key ID, which is a unique identifier used in conjunction with a secret access key to sign requests cryptographically.
  • SK: secret access key used in conjunction with an AK to sign requests cryptographically. It identifies a request sender and prevents the request from being modified.

In AK/SK-based authentication, you can use an AK/SK to sign a request based on the signature algorithm or use a dedicated signature SDK to sign a request. For details about how to sign requests and use the signing SDK API Request Signing Guide.

The signing SDK is only used for signing requests and is different from the SDKs provided by services.

Obtaining the AK/SK

  1. Log in to the management console after registration.
  2. Hover the cursor on the username and choose My Credentials from the drop-down list. On the My Credentials page, click the Access Keys tab.
  3. Click Add Access Key. The Add Access Key dialog box is displayed.
  4. Enter the login password of the current user and the verification code received in the email or on the mobile phone. Click OK to download the access key.

    • For users created in IAM that have not bound any email address or mobile number, only the login password needs to be entered
    • Keep the access key secure.

Demo Code

The following code shows how to sign a request and use AisAccess to send an HTTPS request:

The demo code is classified into the following classes to demonstrate signing and sending the HTTP request:

ResponseProcessUtils: tool class used to process the returned result

ImageTaggingDemo: example class of using Image Tagging. It is used to configure the AK, SK, and region parameters.

  • 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; 
     
    /** 
     * Tool class used to verify the information returned from service access
     */ 
    public class ResponseProcessUtils { 
         
        /** 
         * Print the HTTP status code after the service access is complete.
         *  
         * @param response Response object
         */ 
        public static void processResponseStatus(HttpResponse response) { 
            System.out.println(response.getStatusLine().getStatusCode()); 
        } 
         
        /** 
         * Convert the service access result into a character stream, which is used for displaying the JSON data.
         *  
         * @param response Response object
         * @throws UnsupportedOperationException 
         * @throws IOException 
         */ 
        public static void processResponse(HttpResponse response) throws UnsupportedOperationException, IOException { 
            System.out.println(HttpClientUtils.convertStreamToString(response.getEntity().getContent())); 
        } 
         
        /** 
         * Create the Base64-encoded image file.
         *  
         * @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); 
        } 
         
        /** 
         *  Write a byte array to a file to create a binary file (for example, an image).
         * @param fileName File name
         * @param data 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;
    
    
    /**
     *  Example class of using Image Tagging 
     */
    public class ImageTaggingDemo {
    	//
    	// Example function of using Image Tagging
    	//
    	private static void imageTaggingDemo() throws IOException {
    
    // 1. Configure the basic information for accessing Image Tagging and generate a client connection object.
    
    		AisAccess service = ServiceAccessBuilder.builder()				
                           .ak("######")                       // your ak
                           .sk("######")                       // your sk
                           .region("cn-north-1")               // Configuration of Image Recognition in the CN North-Beijing1 region
                           .connectionTimeout(5000)            // Timeout limit for connecting to the target URL
                           .connectionRequestTimeout(1000)     // Timeout limit for obtaining available connections from the connection pool
                           .socketTimeout(20000)               // Timeout limit for obtaining server response data
                           .build();
    
    		try {
    			//
    			// 2. Construct the parameters required for accessing Image Tagging.
    			//
    			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. Pass the URI and required parameters for accessing Image Tagging.
    			// Pass the parameters in JSON objects and call the service using POST.
    			HttpResponse response = service.post(uri, stringEntity);
    			
    			// 4. Check whether the API call is successful. If 200 is returned, the API call succeeds. Otherwise, it fails.
    			ResponseProcessUtils.processResponseStatus(response);
    			
    			// 5. Process the character stream returned by the service and output the recognition result.
    			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. Disconnect the client connection.
    			service.close();
    		}
    	}
    
    	//
    	// Main entrypoint function
    	//
    	public static void main(String[] args) throws IOException {
    		// Test entrypoint function
    		imageTaggingDemo();
    	}
    }