Cortex Authentication
Cortex supports four different modes for shopper authentication:
- OAuth2 Client Credentials Authentication
- OpenID Connect Authentication
- JWT Token Authentication
- Trusted Header Authentication
OAuth2 Client Credentials Authentication
OAuth2 Client Credentials Authentication is the most frequently used authentication mode. It allows clients to generate either a public (unauthenticated) access token or a registered (authenticated) access token in exchange for a valid username and password. Clients generate access tokens by POST
ing to the oauth2/tokens
endpoint, and then passing the access token in the Authorization
header of all subsequent Cortex requests. This mode is enabled by default.
note
Access tokens can also be passed to Cortex through an auth_token
query parameter, but this approach is considered insecure and deprecated. Support for this query parameter may be removed in future versions of Cortex.
For more information about how clients use this authentication mode, see OAuth2 Authentication.
Configure OAuth2 token expiration
By default, the Cortex authentication tokens expire after 1 week (60 * 60 * 24 * 7
seconds). The expiration time is configured through a tokenExpiry.config
file.
After this file is created, Cortex ignores the default token expiration settings and applies the configuration defined in this file. Changes take effect immediately without having to restart Cortex.
OpenID Connect Authentication
OpenID Connect Authentication allows Cortex to integrate with a third-party Identity Provider for authentication of shoppers.
Identity Provider requirements
The Identity Provider must support with OpenID Connect 1.0 and:
- Provide
public
Subject Identifiers. - Allow authentication using the
client_secret_post
authentication method. - Allow authentication using the Authorization Code Flow.
- Publish an OpenID Connect Discovery document at
.well-known/openid-configuration
. The document must have all required values listed in the specification. - Must not encrypt the ID Token or the UserInfo Endpoint response response.
- Must not require the use of the
nonce
parameter or theacr_values
parameter as part of the Authentication Request. - Must not rely on the
auth_time
claim being validated ID Token Validation.
Tested Identity Providers include:
- Auth0
- Okta
OpenID Connect functionality
If OpenID Connect mode is enabled, Cortex functionality will change as follows:
- The
/oauth2/tokens
endpoint will only allowPUBLIC
authentication (notREGISTERED
authentication). - The root link named
newaccountform
for the registrations resource will be removed; shoppers should register through the Identity Provider directly. - A root link named
openidconnectform
for the openidconnect resource will appear. - A
references
link namedopenidconfiguration
for the openidconnect resource will appear.
When a shopper is authenticated, "claims" from the Identity Provider can be used to update the customer record in Elastic Path Commerce. The mapping of claims to customer profile attributes is controlled by the OpenID Connect Claims Extractor extension point. The default extension (ElasticPathOpenIdClaimsExtractor
) will map claims as follows:
Customer profile key | User info claim key |
---|---|
CP_EMAIL | email |
CP_FIRST_NAME | given_name |
CP_LAST_NAME | family_name |
CP_PHONE | phone_number |
CP_PREF_LOCALE | locale |
If an expected claim is not present, it will be ignored.
For more information about how clients use this authentication mode, see OpenID Connect Authentication.
OpenID Connect configuration
Cortex OpenID Connect authentication can be configured and enabled in two different ways: Either via an authentication.properties
file or via JVM parameters.
The authentication.properties
file must be accessible in one of the following locations:
/ep/conf/secure/authentication.properties
/etc/ep/conf/secure/authentication.properties
${user.home}/ep/conf/secure/authentication.properties
${user.home}/conf/authentication.properties
conf/authentication.properties
A sample authentication.properties
file is shown below:
auth.mode=OIDC
auth.oidc.clientId=your-client-id
auth.oidc.clientSecret=your-client-secret
auth.oidc.uri=https://signin.elasticpath.com
auth.oidc.serializationFormat=FORM
auth.oidc.audienceIdentifier=customers employees
auth.oidc.link.customer.by.email=true
Alternatively, the OpenID Connect configuration properties can be specified through JVM properties. For example: -Dauth.mode=OIDC -Dauth.oidc.clientId=your-client-id
.
The configuration file and JVM properties are described in the table below:
Property | Description | Required? |
---|---|---|
auth.mode | Set to OIDC for OpenID Connect mode, or OAUTH_PASSWORD for OAuth2 Client Credentials mode. | Yes |
auth.oidc.clientId | The client ID generated within the Identity Provider to allow Cortex to authenticate. | Yes |
auth.oidc.clientSecret | The client secret generated within the Identity Provider to allow Cortex to authenticate. | Yes |
auth.oidc.uri | The Identity Provider base URL. Cortex expects to find a discovery document at the .well-known/openid-configuration path for this URL. | Yes |
auth.oidc.serializationFormat | This setting controls whether the body of the Token Request is sent using form serialization or JSON serialization. Set to JSON or FORM . | Yes |
auth.oidc.audienceIdentifier | The audience value allows the Identity Provider to determine the intended recipients of the access token. In other words, it allows the Identity Provider to issue tokens that are only valid for certain purposes. | No |
auth.oidc.link.customer.by.email | If set to true, if no record is found for the subject returned by the Identity Provider, Cortex will search for a matching record based on the email address, and link the subject to that record. | No (defaults to false) |
note
The auth.oidc.link.customer.by.email
setting should only be enabled if the Identity Provider validates the user’s email address, otherwise there is a risk of a bad actor getting access to a shopper's profile.
Migration from OAuth2 Client Credentials to OpenID Connect Authentication
For customers who have been using Elastic Path Commerce in OAuth2 Client Credentials mode and want to migrate to OpenID Connect, we recommend the following steps to ensure that shoppers are able to login to their existing profiles:
- Enable OpenID Connect authentication using the instructions above. Make sure to set the
auth.oidc.link.customer.by.email
property to true. - Use the Import/Export API to export a list of all customer records where
CustomerType = REGISTERED_USER
. - Extract the email addresses from the XML result, and import these into your Identity Provider which should send out emails with a link to allow those shoppers to register and setup new credentials. The Identity Provider should be configured to validate the user's email address before allowing them to login.
- When shoppers later login to the eCommerce site, Cortex will receive a subject that it doesn't recognize. Since the
auth.oidc.link.customer.by.email
property is enabled, it will fallback to a lookup based on the shopper's email address, and associate the subject to that customer record.
JWT Token Authentication
You can use JWT Token Authentication in situations where a trusted third party system has already authenticated a user. JWT Tokens are signed using a private key and validated by Cortex using the corresponding public key to ensure that the trusted system generated the token. Similar to access tokens, JWT Tokens must pass in the Authorization
header of all Cortex requests. This mode is enabled by default.
Configure and generate JWT Token authentication
Before you can pass JWT Tokens to Cortex, you must configure a public key within Cortex. This key corresponds with the private key that the client uses to generate the signed token.
To create a public/private key pair, run the following commands in your terminal:
# Generate private key in PKCS8 format
openssl genpkey -out jwtRS256.key -algorithm RSA -pkeyopt rsa_keygen_bits:2048
# Generate public key in PEM format
openssl rsa -in jwtRS256.key -pubout -outform PEM -out jwtRS256.key.pub
# Display public key
cat jwtRS256.key.pub | grep -v "^----" | tr -d "\n"
Copy the public key add it to the list defined in extensions/database/ext-data/src/main/resources/environments/default/files/conf/cortex/jwtTokenStrategy.config
in your Elastic Path source code, as in the example below:
publicKeys = [ \
# Public key used by JWT authorization Cucumber tests
"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2S73WrOdWC95ifyLhZvr1J9eH0Md/XWKb4wtc3EiztRxi7llc/iZcteeaPTXc3nG1soYm+0kUbp2/PzIPe1yTsdL5zvFDPQtJZL9iv38sRJdjEXHDqKdo+7PKbTbER2bs/U8W5YloC//KbkEFD7MWLqG6ER8N82DLxuAILPnSkqbuhU3t+HOjgw6GpD+2J7FED8ABH18lFXOzqTssZTurJ6zKZb/Mys5Qerg/mqmwpHNKcxWFEh+zv6rTlQkbVHzauG7mWwGvqdTROY/HJRoYjtpWl0eNGoHCXxwo44g0ZdqSC3coPeskVxDnHysAmHb3V9aMxTcphM5vJtRxeQRLwIDAQAB", \
# Second public key used by JWT authorization Cucumber tests
"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAr9/+ME1B2gPjoh1xLzZx+qx91uL3TGHrtTXXPXxkziVBJG44wSQTxTYlXFEyIMWW8Q/VKHVKEmnt/MivyaOey5swNc1EDRZ6igJfI8JpxgRbj7KzR261ATjRbZOn1LU09VYi96inlj6SdV6oP5sLwHZ63X305IA0b1oMsDypgbnWz+F3SiMmPG6DspTQ4HPdcI32SohU7b5ysJDlxt0hiTpz6Ucd1jIhHu3F1HsU9vjswgaIOlaxPnSkgFBjOCS3P8/5Ptyvuye2jNb/q77sLipQM9nm81uBwVue0AzntzgKin1OcXpiuo0TWCxYYtRh9O4ueJfrP/SFN7WjWAsROQIDAQAB", \
# Public key compatible with default testing private key in Account Management
"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0bJzXyIto3wZwrqMtu49ZzGNvb1nWJ3ujROP7aFQyKYqADZ7Y4USa9kychzfs2tw/IQLzfOLQy8oKOVQTbt5KD0osca3T9fP6uMFEpvR1zwcuy5jHUDuyqlgOqAqvySnBCz1/BH6MMQJfITBdcCZCp56uAUBSGW0pfsXwEVad75jdm3tGKCU22cgx7/K1cF3YnbKMAWtKbvW3lLpueohXHvNDIB+xf2Eomp1RRO93n6whkvoKg5cKJug4S17s0cSLrn8oZRp85cmWJ59i7nYqVdY2DpDDTIwpZNIdqauQlzQvInzf1ZEFHl0trDaMV7JJgVQSrDf36hWEF0mQ54X7wIDAQAB" \
]
Cortex accepts the JWT Token if any of the public keys in the file can validate it.
The JWT Token generated by the client might contain multiple claims. For more information, see the JWT Token Authentication Front-end documentation.
There is special consideration given to the "sub" claim, which you can use to identify an existing user in Elastic Path. The way this value is interpreted depends on the value of the COMMERCE/SYSTEM/CUSTOMER/identifier
setting. The value of this setting can be any of the following fields:
GUID
: Look up the customer record with a GUID matching the "sub" claim.ATTRIBUTE_VALUE:{field}
: Look up the customer record with a customer profile attribute value named {field} matching the "sub" claim.SHARED_ID
: Look up the customer record with a shared ID matching the "sub" claim.
This setting supports context values. If a context value key matches the "iss" claim from the JWT token, the value of that context is used to determine how to interpret the "sub" claim.
If the "sub" claim is not specified, Cortex uses the contents of the metadata
claim to generate a single session user. The metadata value is a JSON object encoded with base-64. For example, the user-id
in the metadata is used to generate a shared ID for the single session user.
If the "account" claim is specified, the request is associated to the account with a shared ID matching an account in Elastic Path. This is the same as specifying the x-ep-account-shared-id
header on a request.
Trusted Header Authentication
You can use Trusted Header Authentication if the network configuration protects Cortex access. Access is only accessible by an upstream system that is responsible for authenticating users. In this mode, the user details pass through HTTP
headers which are completely trusted with no additional validation. You must enable this mode, which disables the OAuth2 Client Credentials Authentication.
This mode will only work if the enableTrustedSubjectHeaderMode
JVM parameter is set.
Configure header values
Every Cortex request must have the following header values when you enable this mode:
x-ep-user-id
: The user identifier.x-ep-user-roles
: The role of the shopper. Ensure that this is set to eitherPUBLIC
orREGISTERED
.x-ep-user-scopes
: The scope of the shopper. Ensure that this is set to a valid store code.
The way the x-ep-user-id
header value is interpreted depends on the value of the COMMERCE/SYSTEM/CUSTOMER/identifier
setting. The value of this setting can be any of the following fields:
GUID
: Look up the customer record with a GUID matching thex-ep-user-id
value.ATTRIBUTE_VALUE:{field}
: Look up the customer record with a customer profile attribute value named{field}
matching thex-ep-user-id
value.SHARED_ID
: Look up the customer record with a shared ID matching thex-ep-user-id
value.