Authenticate API Users using an HTTP Authentication Provider

You can define a custom HTTP authentication provider and specify it as the authentication provider for your API. HTTP authentication providers can authenticate API requests without an authentication token. They are the most flexible type of authentication provider. For example, you can specify your API to use a third-party authentication provider, such as OAuth, JSON Web Token (JWT), Single Sign-On (SSO). Custom HTTP authentication providers use the HTTP Auth Provider authentication method.
lac52
You can define a custom HTTP authentication provider and specify it as the authentication provider for your API. HTTP authentication providers can authenticate API requests without an authentication token. They are the most flexible type of authentication provider. For example, you can specify your API to use a third-party authentication provider, such as OAuth, JSON Web Token (JWT), Single Sign-On (SSO). Custom HTTP authentication providers use the 
HTTP Auth Provider
 authentication method.
When you specify an HTTP authentication provider as the authentication provider for your API, the authentication provider determines if incoming REST calls (API users) are authenticated by examining the incoming HTTP request, including the headers and cookies. If the call is authenticated, the authentication provider also determines what roles the API user has.
In this article:
 
 
3
 
 
Add your HTTP Authentication Provider
  1. In API Creator, from the APIs page, click the 
    Auth Providers
     tab.
    The Authentication Providers page appears.
  2. Above the list of authentication providers, click 
    Add
    .
    The Add Authentication Provider window opens.
  3. Select 
    HTTP Auth Provider
     as the authentication method and enter a name for the authentication provider, and then click 
    Add
    .
  4. Click 
    Save
    .
Your HTTP authentication provider is added to your TeamSpace.
Define the Code for your HTTP Authentication Provider
Define the code for the HTTP authentication provider in compliance with JavaScript code conventions. Identity management requires that the HTTP authentication provider (the JavaScript code) follow a specific pattern and return specific properties.
Follow these steps:
 
  1. From the 
    Details
     tab, click the 
    Code
     tab.
    The 
    Authenticate
     code is selected by default.
  2. Define the code for the HTTP authentication provider, and then save your changes. The following sections detail how to define the code for your HTTP authentication provider:
    Your HTTP authentication provider must implement the 
    Authenticate
     code, and typically also implements the 
    Get configuration options
     code and the 
    Configure
     code.
    You can get an understanding of how to define the code by inserting a code example into your code. For more information, see the "Code Examples" section.
The code for your HTTP authentication provider is defined.
Authenticate Code
 
Layer7 Live API Creator
 uses the 
authenticate
 code to examine the request and to determine what roles 
Layer7 Live API Creator
 must assign to the API user using the header information. In the 
authenticate
 code segment, define how the HTTP authentication provider authenticates the call and how it determines the roles that are associated with the call. 
Layer7 Live API Creator
 calls the 
Authenticate
 code for every incoming REST call.
The 
authenticate
 code has the 
result
 variable.
 
The result Variable. Click here to expand...
The 
result
 variable contains the information it receives from 
Layer7 Live API Creator
 from decoding the payload. It has the following attributes:
  •  
    roleNames
     
  •  
    userIdentifier
     
  •  
    userData
     
  •  
    errorMessage
     
  •  
    responseOverride
     
 You can retrieve the data that is stored in the 
userData
 object (in this example, 
name
) of your HTTP authentication providers using the following syntax within your JavaScript code using the 
getDataObjects()
 method:
req.apiKey.getDataObjects().get("abc");
For more information about the req object, see The req Object.
The roleNames attribute
 
You must add the 
roleNames
 attribute to the 
result
 variable in your 
Authenticate
 code. Callers pass requests as the 
servletRequest
 variable. This variable is a Java object of the 
HttpServletRequest
 class. 
Layer7 Live API Creator
 determines if requests are acceptable, typically using this variable, by retrieving the value of HTTP headers and cookies. If 
Layer7 Live API Creator
 determines that the request is acceptable, it assigns a role to the API user. The 
Authenticate
 code does this by adding a role to the 
result.roleNames
 attribute.
For more information about the 
HttpServletRequest
 class, see the Oracle documentation.
A common pattern is to determine which roles you want 
Layer7 Live API Creator
 to assign to the request (the API user). 
Layer7 Live API Creator
 creates a mapping between user-related attributes, like membership in certain groups, or the presence and/or value of certain attributes.
The role that you want the 
Authenticate
 code to add must be a role that is already defined for your API in API Creator.
For more information about how to view the roles that you have defined for your API, see Authorization and Role-Based Endpoint Access.
The 
roleNames
 attribute uses the following syntax:
result.
roleNames
.add("
Role Name
");
For example:
result.
roleNames
.add("Full access");
The userIdentifier attribute
 
You can specify an identifier for the caller by adding the 
userIdentifier
 attribute to the 
result
 variable in your 
Authenticate
 code. Adding an identifier can simplify tracing the call through the logs.
This attribute uses the following syntax:
result.
userIdentifier
= "
User ID
";
The userData attribute
 
You can have 
Layer7 Live API Creator
 can store additional name/value pair information about the API user by adding the 
userData
 attribute to the 
result
 variable. 
Layer7 Live API Creator
 stores this information when it processes the request in your 
Authentication
 code. This information is available in entity (table or view) permissions. For example, you can set a region attribute to restrict access to API users to only certain rows of certain tables.
The 
userData
 attribute uses the following syntax:
result.
userData
["property name"] = "property value";
For example:
result.
userData
["region"] = jwtClaims.body.regionName;
result.
userData
["clearance"] = jwtClaims.body.securityLevel;
The errorMessage attribute
 
You can specify 
Layer7 Live API Creator
 to return an error message to the caller by adding the 
errorMessage
 attribute to the 
result
 variable in your 
Authenticate
 code. If you need more control over the response, including status code and redirects, add the 
responseOverride
 attribute to the 
result
 variable in your 
Authenticate
 code instead of the 
errorMessage
 attribute.
The 
errorMessage
 attribute uses the following syntax:
result.errorMessage = "
The error message
";
 You can also get more detailed logs, for example:
result.
errorMessage
= "Sorry, this request is not acceptable";
log.info("Request to " + restRequest.getRequestURI() + " from " +
restRequest.getRemoteAddr() +
" was rejected because the XYZ header was not specified");
The responseOverride attribute
 
You can optionally take complete control over the response by adding the 
responseOverride
 attribute to the 
result
 variable in your 
Authenticate
 code. For example, the following code snippet specifies that 
Layer7 Live API Creator
 redirect requests that are not acceptable to another URL (this is common in OAuth-type scenarios):
var URI = Java.type("java.net.URI");
var uri = new URI("https://oauth.acme.com");
result.
responseOverride
= Java.type("javax.ws.core.Response").seeOther(uri);
The 
responseOverride
 attribute must be a  type Java object.
For more information about this type of Java object, see the Oracle documentation.
Get configuration options Code
The 
Get configuration options
 code defines the parameters for the information your third-party authentication provider requires. Typical examples of parameters include host names, URLs, public or private keys, and passwords.
These parameters display as fields on the 
Details
 tab for the HTTP authentication provider. If you add parameters, you must configure them for your HTTP authentication provider.
For more information about how to configure the parameters that you have added, see the "Configure the Parameters for your HTTP Authentication Provider" section.
The 
Get configuration options
 code creates a configuration option by calling the 
configInfo.addConfigField()
 method. This code then sets the properties of the returned object. For example, to create a 
hostname
 configuration option, use the following code:
var hostNameField = configInfo.addConfigField();
hostNameField.name = "hostname";
hostNameField.description = "The public key to verify incoming authentication";
hostNameField.display = "Auth host name";
hostNameField.length = 500;
In this example, the 
Auth host name
 parameter, a tooltip with the description, with a maximum value of 500 characters, display on the 
Details
 tab for the HTTP authentication provider. 
Layer7 Live API Creator
 sends the values that the user enters to the 
Configure
 code as the 
hostname
 variable.
The following parameters can be useful, for example, when you require a public key to perform authentication:
  • AuthPublicKeyText
     parameter: 
    Layer7 Live API Creator
     assumes that the value for this parameter is a public key in ASN.1. 
    Layer7 Live API Creator
     automatically decodes the value of this parameter. It and passes the value for this parameter to the 
    Configure
     code as a 
    java.security.PublicKey
     object with the name 
    publicKey
     followed by the value of the 
    AuthPublicKeyText
     parameter. For example, if you defined the 
    AuthPublicKeyText_foo
     parameter, then 
    Layer7 Live API Creator
     makes the decoded public key available in the 
    Configure
     code as the 
    publicKey_foo
     variable. Use this parameter instead of needing to decode public keys.
    For more information about the 
    java.security.PublicKey
     object, see the Oracle documentation
  • AuthPublicKeyAlgorithm
     parameter: 
    Layer7 Live API Creator
     assumes that the value for this parameter is the name of the algorithm for the corresponding public key. For example, if you defined the 
    AuthPublicKeyText_foo
    , then you can specify the algorithm for that key in the 
    AuthPublicKeyAlgorithm_foo
     parameter. 
    Layer7 Live API Creator
     uses that algorithm to decode the public key. Typical values for this parameter are RSA and DSA, but the value depends on your Java environment. 
  • AuthHeaderName
     parameter: This parameter defines in which HTTP header the authentication information comes (assuming it comes as an HTTP header). If your parameter name begins with 
    AuthHeaderName
    , then 
    Layer7 Live API Creator
     automatically caches the authentication result for the request for the duration that is specified in the authentication result. Caching is desirable because decoding and validating an authentication token can be expensive. You can also take care of the caching on your own, but if you define a 
    AuthHeaderName
     configuration property, then 
    Layer7 Live API Creator
     handles the caching.
Configure Code
If you have specified parameters in the 
Get configuration options
 code, you can retrieve the attributes for these parameters by implementing the 
Configure
 code. 
Layer7 Live API Creator
 calls this code once with the user-entered values, and calls it again any time the user changes these attributes. Store anything that must be remembered and available in the 
Authenticate
 code in the 
authProvider.variables
 object, using names of your choice.
For example, you can retrieve the attributes for these parameters, store them for later use, and initialize objects. You do not need to create these objects for every request.
The 
Configure
 code has the 
parameters
 object.
The parameters object. Click here to expand...
The 
parameters
 object shows how 
Layer7 Live API Creator
 should read a parameter within the 
Configure
 code. The 
parameters
 object contains the values that you entered, using the 
name
 attribute that you defined in the 
Get configuration options
 code.
Get login info Code
 
Layer7 Live API Creator
 invokes the 
Get login info
 code each time a caller issues a GET request to the 
@login_info
 endpoint. This call returns an empty result with a status code of 
200
 if everything is OK. The current request is valid for other endpoints. You can also define code to redirect the incoming request to another login mechanism.
The 
Get login info 
code has the 
loginInfo
 variable.
The loginInfo Variable. Click here to expand...
You can have API users authenticate by adding the 
loginInfo
 variable. This variable contains the following attributes: 
  •  
    redirectUrl
     
  •  
    loginStatus
     
  •  
    accountIdent
     
The redirectUrl Attribute
 
You can have the authentication provider redirect incoming requests to a page that handles authentication when the request does not contain enough information to authenticate. You can do this by adding the 
redirectUrl
 attribute to the 
loginInfo
 variable in your 
Get login info
 code.
For OAuth-type, you typically add this attribute to the 
loginInfo
 variable in the 
Get login info
 code.
The loginStatus Attribute
 
You can have the authentication provider set the 
loginStatus
 field to "OK" when the request contains enough information to authenticate by adding the 
loginStatus
 attribute to the 
loginInfo
 variable in your 
Get login info
 code.
The accountIdent Attribute
 
You can have the authentication provider set the 
accountIdent
 field to the API user's account ident when the request contains enough information to authenticate by adding the 
accountIdent
 attribute to the 
loginInfo
 variable in your 
Get login info
 code.
Code Examples
Layer7 Live API Creator
 includes the following JavaScript code examples. They are available from the code editor when you are defining the code for your HTTP authentication provider. If you decide to insert the code examples into your code, insert the same code example (Simple or Shared Secret) into each of the code sections (Authenticate, Get configuration options, Configure, and Get login info). 
Simple Code Examples
The Simple Authenticate code example
The 
Simple Authenticate
 code example illustrates the usage of the 
authenticate
 code. If you decide to use the Simple code example, the 
Simple Authenticate
 code is required.
This code example demonstrates how 
Layer7 Live API Creator
 decodes the payload using the 
publicKey
, examines the claims, and then transfers the information within the claims into the 
result
 variable defined for the authentication provider:
var encodedJwt = servletRequest.getHeader("Authorization");
if ( ! encodedJwt || encodedJwt.trim().length === 0) {
result.errorMessage = "No Authorization header provided";
return;
}
if ( ! encodedJwt.startsWith("Bearer ")) {
result.errorMessage = "Authorization header does not have scheme Bearer";
return;
}
encodedJwt = encodedJwt.substring("Bearer ".length);
var Jwts = Java.type("io.jsonwebtoken.Jwts");
var jwtClaims = Jwts.parser().setSigningKey(publicKey).parseClaimsJws(encodedJwt);
result.userIdentifier = jwtClaims.body.sub;
result.userData["name"] = jwtClaims.body.name;
var groups = JSON.parse(jwtClaims.body.groups);
print("result.userIdentifier:" +result.userIdentifier +
" result.userData:" + result.userData["name"] +
" groups:" + groups ); // Outputs to console
if (groups.indexOf('Managers') > -1) {
result.roleNames.add("Full access");
}
else {
result.errorMessage = "Only managers can use this API";
}
The Simple Get Configuration Options code example
The 
Simple Get Configuration Options
 code example illustrates the usage of the 
Get configuration
 code. If you decide to use the Simple code example, the 
Simple Get Configuration Options
 code is required.
 This code example demonstrates an example of defining the 
Auth public key
, the 
Auth public key algorithm
, and the 
Auth Header name
 parameters:
var pkField = configInfo.addConfigField();
pkField.name = "
AuthPublicKeyText
";
pkField.description = "The public key to verify incoming authentication";
pkField.display = "Auth public key";
pkField.length = 500;
var pkAlgoField = configInfo.addConfigField();
pkAlgoField.name = "
AuthPublicKeyAlgorithm
";
pkAlgoField.description = "The algorithm for the public key";
pkAlgoField.display = "Auth public key algorithm";
pkAlgoField.length = 20;
var jwtHeaderName = configInfo.addConfigField();
jwtHeaderName.name = "
AuthHeaderName
";
jwtHeaderName.description = "Name of HTTP header containing authentication";
jwtHeaderName.display = "Auth Header Name";
jwtHeaderName.length = 20;
The Simple Configure code example
The 
Simple Configure
 code example illustrates the usage of the 
Configure
 code. The following code example demonstrates how you can access the values for parameters that the API call passes into the HTTP authentication provider:
This code snippet is optional for this example to run.
for (var paramName in parameters) {
log.info("Parameter " + paramName +
" has value " +
parameters
[paramName]);
}
The Simple Get Login Info code example
The 
Simple Get Login Info
 code example illustrates the usage of the 
Get login info
 code. The following code example demonstrates how to return a successful login status or redirect the caller to another login mechanism:
var auth = servletRequest.getHeader("Authorization");
if (auth && auth.startsWith("Bearer ")) {
// In this very simple example, we just assume that the header is OK
// Obviously, in the real world, you would want to verify that!
loginInfo.loginStatus
= "OK";
// The authentication information should provide you with enough
// information to determine the caller's account. Here we just
// hard-code it.
loginInfo.accountIdent
= 1000;
return;
}
// If the request did not contain enough information, let's send back
// a URL to tell the caller where to go for authentication
if ( ! authProvider.variables["randomState"]) {
print("Get login info: generate random state");
var RG = Java.type("com.kahuna.logic.lib.crypto.RandomGenerator");
authProvider.variables.randomState = RG.generateRandomString(50);
}
var clientId = "12345678901234567890";
var redirectUri = "http://localhost:8080/APICreator";
loginInfo.redirectUrl
=
"https://dev-1234567.oktapreview.com/oauth2/default/v1/authorize?client_id=" +
clientId + "&response_type=token&scope=openid&redirect_uri=" + redirectUri +
"&state=" + authProvider.variables.randomState +
"&nonce=" + authProvider.variables.randomState;
Shared Secret Code Examples
The Shared Secret Authenticate code example
The 
Shared Secret Authenticate
 code example illustrates the usage of the 
Authenticate
 code. If you decide to use the Shared Secret code example, the 
Shared Secret Authenticate
 code is required.
This code example demonstrates how to decode the payload using the 
secretKey
 variable, how to examine the claims, and how to transfer the information within the claims into the 
result
 variable that is defined for the authentication provider:
// A single request may contain more than one Authorization header
var authHeaderEnum = servletRequest.getHeaders("Authorization");
var encodedJwt = null;
while (authHeaderEnum.hasMoreElements()) {
print("Looking at Auth header");
var headerValue = authHeaderEnum.nextElement();
if ( ! headerValue || headerValue.trim().length === 0 || ! headerValue.startsWith("Bearer ")) {
print("Disregarding Auth header");
continue;
}
encodedJwt = headerValue;
break;
}
if ( ! encodedJwt) {
result.errorMessage = "No valid Authorization header provided";
return;
}
encodedJwt = encodedJwt.substring("Bearer ".length);
var Jwts = Java.type("io.jsonwebtoken.Jwts");
// The secretKey variable was set up in the Configure code
var jwtClaims = Jwts.parser().setSigningKey(authProvider.variables.secretKey).parseClaimsJws(encodedJwt);
result.userIdentifier = jwtClaims.body.Email;
result.userData["name"] = jwtClaims.body.GivenName;
if (jwtClaims.body.Role && jwtClaims.body.Role.indexOf('Manager') > -1) {
result.roleNames.add("Full access");
}
else {
result.errorMessage = "Only managers can use this API";
}
The Shared Secret Get Configuration Options code example
The 
Shared Secret Get Configuration Options
 code example illustrates the usage of the 
Get Configuration Options
 code. This code example demonstrates an example of defining the 
SharedSecret 
 and the 
SharedSecretAlgorithm
 parameters. If you decide to use the 
Shared Secret
 code example, the 
Shared Secret Configuration Options
 code is required.
var pkField = configInfo.addConfigField();
pkField.name = "
SharedSecret
";
pkField.description = "The shared secret";
pkField.display = "Shared secret";
pkField.length = 500;
var pkAlgoField = configInfo.addConfigField();
pkAlgoField.name = "
SharedSecretAlgorithm
";
pkAlgoField.description = "The algorithm for the shared key";
pkAlgoField.display = "Shared key algorithm";
pkAlgoField.length = 20;
The Shared Secret Configure code example
The 
Shared Secret Configure
 example code illustrates the usage of the 
Configure
 code. If you decide to use the Shared Secret code example, the 
Shared Secret Configure
 code is required.
This code example uses the 
parameters
 object to set the 
secretBytes
 variable and the 
SecretKeySpec
 object. 
Layer7 Live API Creator
 uses this variable and object in the 
Authenticate
 code:
var SecretKeySpec = Java.type("javax.crypto.spec.SecretKeySpec");
var secretBytes =
parameters
.SharedSecret.getBytes();
authProvider.variables.secretKey = new SecretKeySpec(secretBytes,
parameters
.SharedSecretAlgorithm);
Configure the Parameters for your HTTP Authentication Provider
If your third-party authentication provider requires information from the HTTP authentication provider and you have defined these parameters in the 
Get configuration options
 code, the parameters display as fields on the 
Details
 tab for the HTTP authentication provider. You must enter values for these parameters.
Follow these steps:
 
  1. From the Authentication Providers page, click the 
    Details
     tab.
  2. In the 
    Parameters
     section of the page, enter values for the parameters, and then save your changes.
The parameters for your authentication provider are configured.
Specify the HTTP Authentication Provider as the Authentication Provider for your API
When you define an HTTP authentication provider and you specify it as the authentication provider for your API, 
Layer7 Live API Creator
 does not use the API users that you define in API Creator.
Follow these steps:
 
  1. From the Authentication Providers page, click the 
    APIs
     tab.
    The APIs page appears.
  2. Open the API for which you want to specify the authentication provider.
    The API Properties Overview page appears.
  3. Click the 
    Details 
    tab.
  4. Select the HTTP authentication provider that you defined as the authentication provider for your API from the 
    Authentication provider
     drop-down, and then save your changes.
    For more information about the other fields that are on this tab, see API Properties.
The HTTP authentication provider is specified as the authentication provider for your API.
Use Globals with the HTTP Authentication Provider
You can further secure your API endpoints using globals. Create the globals within the roles that are defined within your API.