AI Gateway supports global authentication and consumer authorization to ensure that only authorized requests can access your services. This topic describes how consumers can securely access resources using authentication and authorization in AI Gateway.
Background information
Global authentication and authorization typically apply to business-to-consumer (B2C) scenarios, such as unified logon authentication. In contrast, consumer authentication for APIs applies to business-to-business (B2B) scenarios, such as granting API access to partners.
Comparison item | Global authentication and authorization | Consumer authorization |
Scenarios | B2C scenarios, such as unified logon authentication. | B2B scenarios, such as granting API access to partners. |
Core difference | When you enable authentication, authorization is also enabled. | After you enable authentication, you must perform additional authorization configurations. |
Configuration entry | . |
|
Authentication method configuration (JWT authentication is used as an example) |
|
|
Authorization method configuration | When you create a configuration, specify the Domain Names and Paths for the blacklist or whitelist.
|
|
Notes
When a user enables consumer authentication, the authentication policy takes effect immediately. If the API is published at this time, but no consumer or authorization rules are configured for the API, all access requests are denied by default.
Use consumer authentication and authorization
JWT authentication
JWT authentication flow
The client sends an authentication request that contains the end user's username and password to AI Gateway.
The gateway forwards the request to the backend service.
The backend service retrieves the verification information, such as the username and password, from the request. After verifying the information, the backend service uses a private key to generate a standard token and returns it to the gateway.
The gateway returns the response that contains the token to the client. The client must cache this token locally.
The client sends a business request that contains the token to AI Gateway.
The gateway uses the public key that you configured to verify the token in the request. After the token is verified, the gateway forwards the request to the backend service in pass-through mode.
The backend service processes the business request and returns a response.
The gateway returns the business response to the client.
The following sections describe how to generate a token, how a client sends a request to the gateway, and how the gateway uses a public key to verify the token.
Generate a token in the authentication service
The following section uses a Java code sample to describe how to generate a token. You can also use related tools to generate a key pair in other programming languages.
Create a Maven project and add the required dependencies.
First, create a Maven project and add the following dependency:
<dependency> <groupId>org.bitbucket.b_c</groupId> <artifactId>jose4j</artifactId> <version>0.7.0</version> </dependency>Select a method to generate the token.
You can generate the token using the default symmetric key sample or the asymmetric key sample. Select a method based on your requirements:
Use the default symmetric key sample to generate a token
Sample code:
package org.example; import java.io.UnsupportedEncodingException; import java.security.PrivateKey; import org.jose4j.base64url.Base64; import org.jose4j.json.JsonUtil; import org.jose4j.jwk.OctJwkGenerator; import org.jose4j.jwk.OctetSequenceJsonWebKey; import org.jose4j.jws.AlgorithmIdentifiers; import org.jose4j.jws.JsonWebSignature; import org.jose4j.jwt.JwtClaims; import org.jose4j.jwt.NumericDate; import org.jose4j.keys.HmacKey; import org.jose4j.lang.JoseException; import sun.lwawt.macosx.CSystemTray; public class Main { public static void main(String[] args) throws JoseException, UnsupportedEncodingException { // Use the preceding example in this topic. String privateKeyJson = "{\n" + " \"k\": \"VoBG-oyqVoyCr9G56ozmq8n_rlDDyYMQOd_DO4GOkEY\",\n" + " \"kty\": \"oct\",\n" + " \"alg\": \"HS256\",\n" + "}"; JwtClaims claims = new JwtClaims(); claims.setGeneratedJwtId(); claims.setIssuedAtToNow(); // Set the expiration time to a value that is less than seven days. NumericDate date = NumericDate.now(); date.addSeconds(120*60); claims.setExpirationTime(date); claims.setNotBeforeMinutesInThePast(1); // Add custom parameters. All values must be of the STRING type. // Set the consumer ID. claims.setClaim("uid", "11215ac069234abcb8944232b79ae711"); JsonWebSignature jws = new JsonWebSignature(); // Set the encryption algorithm. jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.HMAC_SHA256); jws.setKey(new HmacKey(Base64.decode(JsonUtil.parseJson(privateKeyJson).get("k").toString()))); jws.setPayload(claims.toJson()); String jwtResult = jws.getCompactSerialization(); System.out.println("Generate Json Web token , result is \n " + jwtResult); } }Description of code parameters:
privateKeyJson: The JSON Web Key Set (JWKS) that is used when you create the consumer. You can record the JWKS when you create the consumer or retrieve it from the consumer's basic information page after the consumer is created.Set the consumer ID. This is specified by
claims.setClaim("uid", "11215ac069234abcb8944232b79ae711"). The consumer ID is generated by default in the console when you create the consumer. You can also modify the ID based on your business logic. After you create the consumer, you can retrieve the consumer ID from the consumer's basic information page.Set the encryption algorithm. This is specified by
jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.HMAC_SHA256). The encryption algorithm must be the same as the algorithm specified in the JWKS.NoteThe supported encryption algorithms are ES256, ES384, ES512, RS256, RS384, RS512, PS256, PS384, PS512, HS256, HS384, HS512, and EdDSA.
When you use symmetric encryption, you must decode "k".
jws.setKey(new HmacKey(Base64.decode(JsonUtil.parseJson(privateKeyJson).get("k").toString())));
Set the expiration time. The expiration time must be less than seven days. After the token expires, you must generate a new token to ensure security.
... NumericDate date = NumericDate.now(); date.addSeconds(120*60); claims.setExpirationTime(date); claims.setNotBeforeMinutesInThePast(1); ...You can add custom parameters to the PAYLOAD of the JWKS as needed.
Use the asymmetric key sample to generate a token
Sample code:
package org.example; import java.io.UnsupportedEncodingException; import java.security.PrivateKey; import org.jose4j.base64url.Base64; import org.jose4j.json.JsonUtil; import org.jose4j.jwk.OctJwkGenerator; import org.jose4j.jwk.OctetSequenceJsonWebKey; import org.jose4j.jws.AlgorithmIdentifiers; import org.jose4j.jws.JsonWebSignature; import org.jose4j.jwt.JwtClaims; import org.jose4j.jwt.NumericDate; import org.jose4j.keys.HmacKey; import org.jose4j.lang.JoseException; import sun.lwawt.macosx.CSystemTray; public class Main { public static void main(String[] args) throws JoseException, UnsupportedEncodingException { // Use the preceding example in this topic. String privateKeyJson = "{\n" + " \"k\": \"VoBG-oyqVoyCr9G56ozmq8n_rlDDyYMQOd_DO4GOkEY\",\n" + " \"kty\": \"oct\",\n" + " \"alg\": \"HS256\",\n" + "}"; JwtClaims claims = new JwtClaims(); claims.setGeneratedJwtId(); claims.setIssuedAtToNow(); // Set the expiration time to a value that is less than seven days. NumericDate date = NumericDate.now(); date.addSeconds(120*60); claims.setExpirationTime(date); claims.setNotBeforeMinutesInThePast(1); // Add custom parameters. All values must be of the STRING type. // Set the consumer ID. claims.setClaim("uid", "11215ac069234abcb8944232b79ae711"); JsonWebSignature jws = new JsonWebSignature(); // Set the encryption algorithm. jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.HMAC_SHA256); jws.setKey(new HmacKey(Base64.decode(JsonUtil.parseJson(privateKeyJson).get("k").toString()))); jws.setPayload(claims.toJson()); String jwtResult = jws.getCompactSerialization(); System.out.println("Generate Json Web token , result is \n " + jwtResult); } }Description of code parameters:
Set
privateKeyJson, the consumer ID, and the expiration time. The settings are the same as those for the symmetric encryption algorithm.Set the encryption algorithm. This is specified by
jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.RSA_USING_SHA256). The encryption algorithm must be the same as the algorithm specified in the JWKS.For an asymmetric key encryption algorithm, you must use its private key to encrypt data.
... jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.RSA_USING_SHA256); PrivateKey privateKey = new RsaJsonWebKey(JsonUtil.parseJson(privateKeyJson)).getPrivateKey(); jws.setKey(privateKey); ...You can add custom parameters to the
PAYLOADof the JWKS as needed.
Send a business request from the client to the gateway
AI Gateway supports passing tokens in the header. You can customize the name of the request header and the prefix of the token. When a request is authenticated, the key and prefix must be the same as those configured for the consumer authentication method.
If the request does not carry a JWT, the HTTP status code 401 is returned.
curl http://xxx.hello.com/testIf the request carries an invalid JWT, the HTTP status code 401 is returned.
curl http://xxx.hello.com/test -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IjEyMyJ9.eyJpc3MiOiJhYmNkIiwic3ViIjoidGVzdCIsImlhdCI6MTY2NTY2MDUyNywiZXhwIjoxODY1NjczODE5fQ.-vBSV0bKeDwQcuS6eeSZN9dLTUnSnZVk8eVCXdooCQ1'If the request carries a JWT but the consumer represented by the JWT is not granted permission to access the API, the HTTP status code 403 is returned.
# consumer1 is not authorized to access the API specified by the following path curl 'http://xxx.example.com/test' -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IjEyMyJ9.eyJpc3MiOiJhYmNkIiwic3ViIjoidGVzdCIsImlhdCI6MTY2NTY2MDUyNywiZXhwIjoxODY1NjczODE5fQ.-vBSV0bKeDwQcuS6eeSZN9dLTUnSnZVk8eVCXdooCQ4'
Verify the token request on the server
The server verifies the token in the following three steps:
When the server receives a user request, it checks whether the request carries a token. If the request does not carry a token, the request is denied and the HTTP status code 401 is returned.
If the request carries a token, the server uses the public key configured in the consumer's JWKS to verify whether the token is valid. If the token is invalid or has expired, the request is denied and the HTTP status code 401 is returned.
If the token is valid, the server checks whether the consumer represented by the token is granted permission to access the API.
Common error codes
HTTP status code | Error message | Cause |
401 | Jwt missing | The request header does not provide a JWT. |
401 | Jwt expired | The JWT has expired. |
401 | Jwt verification fails | The JWT payload verification failed. For example, the iss value does not match. |
403 | Access Denied | You are not authorized to access the current API. |
API key authentication
If the consumer authentication and authorization policy is not enabled for the Model API, you can directly access the API.
If the consumer authentication and authorization policy is enabled for the Model API but no permissions are granted, the HTTP status code 401 is returned.
The debugging procedure is similar to the calling procedure. This topic uses the debugging of a Model API as an example.
The API key credentials can be passed from the following three sources:
Default source: Authorization: <Bearer> Token.
Custom Header: Specify the name of the header parameter.
Custom Query parameter: Specify the name of the query parameter.
Default source
When you debug a Model API, you can set the API key in the HTTP request header on the debugging page to ensure request authentication. The procedure is as follows:
In the Authorization field, use Bearer as the prefix.
Make sure that a space exists between Bearer and the API key.
Custom Header
In addition to standard request headers, you can define custom HTTP request headers to pass specific information.
Custom Query parameter
In the request URL, you can add custom query parameters to pass additional information or configurations.
Related error codes
HTTP status code | Error message | Cause |
401 | Request denied by Key Auth check. Multiple API keys found in request. | The request provides multiple API keys. |
401 | Request denied by Key Auth check. No API key found in request. | The request does not provide an API key. |
401 | Request denied by Key Auth check. Invalid API key. | The current API key is not allowed to access the API. |
403 | Request denied by Key Auth check. Unauthorized consumer. | The requester does not have permission to access the API. |
References
For more information about how to authorize and manage APIs, see Authorization management.