Ceptor supports OAuth2 / OpenID Connect (OIDC) and exchanging JWT tokens with 3rd parties.
To use these federations, you should add the authentication plugin |
This support is an integral part of Ceptor API Management but can also be used outside the API Management scope as a means for federation of identities both from Ceptor to Service Providers and from OpenID or OAuth2 Providers to Ceptor.
Ceptor supports the different variations of OAuth2 flows, including:
For each scope, you can configure which attributes are added to the various types of tokens, ID Token, Access Token and Userinfo JSON.
Available flows can be restricted for specific clients, optionally limiting them to use only specific flows and scopes.
These settings are stored directly in the Federation JSON Root object in the configuration for the session controller.
Specify which OAuth2 Datastore implementation you would like to use
Out of the box, Ceptor has 3 different datastores available.
You also have the option of providing your own implementation in case you use a different system to store your OAuth2 clients in. Implementations must implement the Java Interface dk.itp.security.authentication.oauth.data.IOAuthDataStore
which looks like this:
public interface IOAuthDataStore { /** * Gives the datastore its configuration * @param config Configuration */ public void setConfiguration(Properties config) throws ConfigurationException; /** * Gives the datastore its configuration * @param config Configuration * @param json JSON Configuration */ public void setConfiguration(Properties config, JSONObject json) throws ConfigurationException, JSONException; /** * Return a list of known client IDs * @return List of known client IDs */ public Collection<String> getKnownClientIDs(); /** * Returns known ClientData from a clientID * * @param clientID Client ID * @return Client Data - includes secret, valid scopes, valid redirect URIs etc. */ public ClientData getClientData(String clientID); default void initialize(PTSServer sessionController) { } } public class ClientData { public enum AccessTokenType { JWT, UUID, RFC9068, RFC9060UP } /** Client ID */ public String clientID; /** Client secret */ public String clientSecret; /** Valid OAuth2 grant type; implicit, authorization_code */ public Collection<String> validGrantTypes; /** Valid scopes, e.g. email, profile, name, photo */ public Collection<String> allowedScopes; /** Allowed redirect URIs */ public Collection<String> allowedUris; /** Allowed logout URIs */ public Collection<String> allowedLogoutUris; /** Number of seconds the access token is valid for */ public int accessTokenValiditySeconds; /** Number of seconds the refresh token is valid for */ public int refreshTokenValiditySeconds; /** The maximum expiration time in minutes allowed */ public int maximumIdTokenExpirationMinutes; /** Name of token configuration to use with this client */ public String tokenname; /** Type of access token to generate */ public AccessTokenType accessTokenType; /** A list of roles for this client - could be roles for an API partner */ public List<String> roles; public Map<String, Object> properties = new LinkedHashMap<>(); public String toJSON() { JSONObject jo = new JSONObject(); try { jo.put("client_id", clientID); jo.put("client_secret", clientSecret); jo.put("valid_grant_types", validGrantTypes); jo.put("allowed_scopes", allowedScopes); jo.put("allowed_uris", allowedUris); jo.put("allowed_logout_uris", allowedLogoutUris); jo.put("accesstoken_valid_seconds", accessTokenValiditySeconds); jo.put("refreshtoken_validity_seconds", refreshTokenValiditySeconds); jo.put("maximum_idtoken_expiration_minutes", maximumIdTokenExpirationMinutes); jo.put("tokenname", tokenname); jo.put("accesstoken_type", accessTokenType.toString()); for(String key : properties.keySet()) { if (!jo.has(key)) jo.put(key, properties.get(key)); } return jo.toString(); } catch(JSONException e) { return "{\"error\": \"" + JSONObject.quote(e.toString())+"\"}"; } } public static ClientData fromJSON(JSONObject jo) throws JSONException { ClientData cd = new ClientData(); cd.clientID = jo.optString("client_id", null); cd.clientSecret = jo.optString("client_secret", null); cd.validGrantTypes = fromJA(jo.optJSONArray("valid_grant_types")); cd.allowedScopes = fromJA(jo.optJSONArray("allowed_scopes")); cd.allowedUris = fromJA(jo.optJSONArray("allowed_uris")); cd.allowedLogoutUris = fromJA(jo.optJSONArray("allowed_logout_uris")); cd.accessTokenValiditySeconds = jo.optInt("accesstoken_valid_seconds"); cd.refreshTokenValiditySeconds = jo.optInt("refreshTokenValiditySeconds"); cd.maximumIdTokenExpirationMinutes = jo.optInt("maximumIdTokenExpirationMinutes"); cd.tokenname = jo.optString("tokenname", null); cd.accessTokenType = AccessTokenType.valueOf(jo.optString("accesstoken_type", "UUID").toUpperCase()); for(String key : JSONObject.getNames(jo)) { cd.properties.put(key, jo.get(key)); } return cd; } private static Collection<String> fromJA(JSONArray ja) throws JSONException { if (ja == null || ja.length() == 0) return Collections.emptyList(); List<String> result = new ArrayList<>(ja.length()); for(int i = 0; i < ja.length(); i++) { result.add(ja.getString(i)); } return result; } } |
Default: dk.itp.security.authentication.oauth.data.properties.OAuth2DataStoreProperties
JSON key is oauth2.datastoreclass
Specify which OAuth2 Access Token Datastore implementation to use.
This is used to store issued Access Tokens where they can be looked up when they are used as bearer tokens in API calls - or for calling the UserInfo endpoint.
The following implementations are available:
You also have the option of providing your own implementation. Implementations must implement the Java Interface dk.itp.security.authentication.oauth.data.IAccessTokenDataStore
which looks like this:
public interface IAccessTokenDataStore { /** * Lookup a previously stored set of information for a particular client ID and access token * * @param clientId Client ID - might be null if session is created from a ticket/bearer token * @param refreshToken Refresh Token * @return RefreshTokenInfo loaded from datastore. */ public AccessTokenInfo lookupToken(String clientId, String accessToken); /** * Lookup a previously stored set of information for a particular client ID and authorization code * An access token can only be looked up once - after that, it is marked as being used and cannot be reused. * * @param clientId Client ID * @param refreshToken Refresh Token * @return RefreshTokenInfo loaded from datastore. */ public AccessTokenInfo lookupTokenFromCode(String clientId, String authorizationCode); /** * Store the info in the data store. * * @param info Access Token to store */ public void storeAccesToken(AccessTokenInfo info); /** * Revoke an existing access token * * @param info Access Token to revoke */ public void revokeAccessToken(AccessTokenInfo info); /** * Called to initialize this datastore, after configuration has been set * @param sessioncontroller */ public void start(PTSServer sessioncontroller) throws ConfigurationException; /** * Gives this datastore a chance to stop and release any resources it might have */ public void stop(); /** * Gives the datastore its configuration * @param config Configuration */ public void setConfiguration(Properties config); /** * Gives the datastore its configuration * @param config Configuration * @param json JSON Configuration */ default public void setConfiguration(Properties config, JSONObject json) throws ConfigurationException, JSONException { setConfiguration(config); } } public class AccessTokenInfo implements Serializable { private static final long serialVersionUID = 1L; /** The access token */ public String access_token; /** An ID token that might have be generated along with the access token */ public String id_token; /** Client ID */ public String clientid; /** Redirect URL */ public String redirectUri; /** Refresh token, if any */ public String refreshToken; /** Expiration time in seconds of the access token*/ public int accessTokenExpireSeconds; /** Authorization code which can be used to obtain this access token */ public String authorizationCode; /** The persisted session */ public byte[] persistedSession; /* RFC7636 / PKCE support */ /** Optional code_challenge - might be hashed */ public String code_challenge; /** code_challenge method - either plain or S256 */ public String code_challenge_method; // --- Information needed for introspection --- /** The requested scope */ public String scope; /** Expires at (seconds) */ public long expiresAt; /** Issued at (seconds) */ public long issuedAt; /** Subject */ public String sub; /** Username */ public String username; /** Audience */ public String audience; /** Issuer */ public String issuer; /** Token ID */ public String jti; } |
Default: dk.itp.security.authentication.oauth.data.AccessTokenMemoryStore
JSON key is oauth2.accesstoken.datastoreclass
Specify which OAuth2 Refresh Token Datastore implementation to use.
This is used to store issued Refresh Tokens where they can be looked up when the token endpoint (or introspection endpoint) is called with the token.
The following implementations are available:
You also have the option of providing your own implementation. Implementations must implement the Java Interface dk.itp.security.authentication.oauth.data.IRefreshTokenDataStore
which looks like this:
public interface IRefreshTokenDataStore { /** * Lookup a previously stored set of session data for a particular client ID and refreshToken * * @param clientId Client ID * @param refreshToken Refresh Token * @return RefreshTokenInfo loaded from datastore. */ public RefreshTokenInfo lookupToken(String clientId, String refreshToken); /** * Store the info in the data store. * * @param info Refresh Token to store */ public void storeRefreshToken(RefreshTokenInfo info); /** * Revoke an existing refresh token * * @param info Refresh token to revoke */ public void revokeRefreshToken(RefreshTokenInfo info); /** * Gives the datastore its configuration * @param config Configuration */ public void setConfiguration(Properties config); /** * Gives the datastore its configuration * @param config Configuration * @param json JSON Configuration */ default public void setConfiguration(Properties config, JSONObject json) throws ConfigurationException, JSONException { setConfiguration(config); } /** * Called to initialize this datastore, after configuration has been set * @param sessioncontroller */ public void start(PTSServer sessioncontroller) throws ConfigurationException; /** * Gives this datastore a chance to stop and release any resources it might have */ public void stop(); } public class RefreshTokenInfo implements Serializable { private static final long serialVersionUID = 1L; /** The refresh token */ public String refreshToken; /** The client ID this token is valid for */ public String clientID; /** Expire time in msecs */ public long expiresAt; /** Created at in msecs */ public long createdAt; /** The persisted session */ public byte[] persistedSession; } |
Default: dk.itp.security.authentication.oauth.data.RefreshTokenMemoryStore
JSON key is oauth2.refreshtoken.datastoreclass
This is the name of the datastore to use - used by the SQL implementations - must match one of the datastores configured - see Getting Started with Ceptor API Management and Datastores
Default: datastore-primary
JSON key is oauth2.datastorename
This is the name of the token to use by default if nothing else is provided - each token definition contains separate configuration for which attributes are issued, and you can specify for specific clients that you want to issue non-default tokens to them.
Default: None
JSON key is oauth2.defaulttoken
Specify the timeout in seconds for how long time issued authorization codes will live before they expire. You should keep this value low.
Default: 120
JSON key is oauth2.authorizationcode.timeoutseconds
This is kept in a JSON object called proxy. Note that this configuration is shared with the OpenID Connect / JWT Federation configuration.
Check to enable HTTP proxy.
Default: false
JSON key is enabled
Maximum acceptable time difference in minutes - allows for clock skew between issuer and service provider.
Default: 2
JSON key is host
TCP Port number of proxy server
Default: 8080
JSON key is port
Userid to authenticate to proxy server.
Default: None
JSON key is user
Password needed to authenticate to proxy server - can be encrypted, see Encrypting or Obfuscating Passwords
Default: None
JSON key is password
Hostname matching this pattern will not be proxied
Default: None
JSON key is noproxyfor
Tokens specify either how tokens are issued to Service Providers / Partners / Clients or how tokens issued by other OAuth2 or OpenID Connect Identity Providers are validated.
Here, you can add any number of tokens to the list - remember to set the default token to use in the settings.
Default: None
JSON key is tokens
For each individual token, you can specify the following setttings:
Configuration for each token is stored as a JSON Object within the tokens JSON array within the federations JSON.
Specify the name of the token - this name can be used in client/partner definitions to point to a specific token to issue for a specific client.
Default: None
JSON key is name
Here, you can specify a description for the token
Default: None
JSON key is description
The issuer name - corresponds to the "iss" attribute in the token.
Default:
JSON key is issuer
Specify the ID of the key - this ID is used in the JWKS metadata that can be sent to clients.
Default:
JSON key is keyid
Check to include this key in the JWKS metadata send to clients,
Default: false
JSON key is include.in.jwks.metadata
Specify the Signing algorithm to use when issuing tokens - beware of using "None" - since it allows anyone to spoof the tokens and create their own.
The names starting with RS require private/public keypairs (signed by the private key and validated using the public key) and the names starting with HS use a shared secret key.
Default: RS256
JSON key is algorithm
Specify expiration time in minutes of issued tokens.
Default: 10
JSON key is expiration.minutes
When a token is issued, its nbf (not-before) attribute is set to the current time - but to allow for difference in clocks, it can be a good idea to set this time slightly in the past, this allows you to specify how many minutes in the past.
Default: 2
JSON key is notbefore.minutes.in.past
List of attributes/claims that are always added to the token. In addition, depending on scopes requested, there might be other claims / attributes in the token, since each scope has a list of different claims/attributes in the various types of tokens.
Default: None
JSON key is claims as a JSON array containing the claims issued.
Check if this token is OpenID Connnect compliant - if it is, specific settings are verified, e.g. issuer name should start with https://
Default: false
JSON key is openidconnect
This script is called with the access token JSON payload (if the access token type is JWT and not UUID) before it is signed - this gives the script a chance to modify any of its content before issuing it.
See below for more details in input.
Default: None
JSON key is script.accesstoken
This script is called with the ID token JSON payload - this gives the script a chance to modify any of its content before issuing it.
See below for more details in input.
Default: None
JSON key is script.idtoken
This script is called with the userinfo JSON object before it is sent to the client, the script can modify any attribute (or rewrite it completely).
Default: None
JSON key is script.userinfo
For the 3 script types above, see the code completion in the editor for detailed information about which variables are available to the script. On high level, this is:
The script can return a modified token / JSON userinfo as a string. Example:
|
This script is called whenever a token exchange is requested.
Default: None
JSON key is script.tokenexchange
Javascript, Groovy or Python code is executed to process the token exchange input, add validation or provide extra information for use when the access token is generated.
Variables
If the subject_token was found and recognized as an earlier issued token, the context.session is populated with the contents of the session. If not, the token is available in context.session.ticket and you can parse it and populate the session with the results. If context.session.userid is empty when the script returns, it is assumed that the parsing failed and an error will be sent back to the client informing that the token was not valid. If an actor token was provided and recognized, the session of the actor is populated with information - if not recognized you can find the token (along with any other input parameters from the request in the input java.util.Properties object. In this script, you can modify the session contents before the final access token is generated. The access token will be generated by default as a copy of the incoming subject_token but with an attribute "act" added with the subject of the actor token in the "sub" field, and the client_id in the "client_id" field of the "act" object. In the access token generation script, you get a chance to modify the properties after the token is generated before it gets signed - the token exchange script allows you to modify the session context before the resulting access token is generated.
|
Name of the attribute to copy userid from - if not specified, the standard subject (sub) attribute is used instead.
Default: None
JSON key is userid.attribute.name
Name of the attribute to copy username from.
Default: name
JSON key is username.attribute.name
Name of the attribute to copy user groups/roles from.
Default: groups
JSON key is role.attribute.name
When copying user groups/roles from the token into the session, only groups matching the specified pattern will be used.
Default: *
JSON key is role.pattern
If checked, insecure tokens, such as those using weak keys, or crypto algorithm None will be allowed.
Default: false
JSON key is relax.key.checks
If checked, the session will not expire using normal idle timeout, but it will expire at the exact time that the issued token expires. Check this to disable idle-timeout for sessions.
Default: false
JSON key is expires.at.exact.time
Check this if subject (sub) attribute must be present in the token.
Default: false
JSON key is require.subject
If set, specify one or more valid audience strings that this token must match - if not set, audience (aud attribute) is not checked.
Default: No limits
JSON key is validaudiences as a JSON Array of strings
Specify the number of seconds to allow for clock skew / time difference when validating nfb/exp attributes - setting this to a high value will allow tokens x seconds after they have expired or x seconds before they become valid. This can be useful to allow for a certain difference in clocks between machines.
Default: 0
JSON key is clockskew.seconds
Patter matching list of attributtes to store in session - if attribute in token matches this pattern, it will be stored in the session.
If Custom Attribute Mapping is specified, "Attributes to store" is not used, and t he custom attribute mapping is used instead. |
Default: *
JSON key is attributes.to.store.in.session
Allows customized mapping of attribute values.
Each attribute is stored as a JSON object with key and value attributes inside it.
Key is one of:
The value is a string, where macros are replaced with the appropriate contents - a macro can be %{claim:XXXX
} where XXXX is the name of a claim key in the JSON JWT token, or token returned from an identity provider such as facebook.
Macros are in the form %{type:name} where type can be claim, base64, urlencode, htmlencode, base64decode, urldecode - the default is claim if not specified. If set to e.g. base64, the value will be treated as base64 and decoded.
Like with Ceptor Gateway - Scripts and Macros you can use scripts (javascript, python or groovy) and %{rewrite} macros to do more advanced transformations of values. When scripts are used, the variable context will point to an object which contains two variables; session pointing to the users Ceptor Session, and jo pointing to a JSONObject containing the claims to map.
Examples:
%{claim:firstName} %{claim.lastName} %{script}salary(); function salary() {var json = JSON.from(context.jo.toJSONString()); return (json.monthlySalary * 12) + json.yearlyBonus;} |
Default: None
JSON key is fieldmappers - a JSON Array of JSON Objects
Issuer keys are stored in the JSON Object keystore, within the token JSON object - except for "secretkey" which is stored directly within the token itself.
Secret key, if signing algorithm is one of the HS* algoritms
Default: None
JSON key is secretkey
Name of JCE provider - if left blank, platform default is used. Can be set to e.g. Luna to support hardware crypto providers assuming Luna JCE provider is installed.
Default: None
JSON key is provider
Keystore type, usually PKCS12 or JKS
Default: PKCS12
JSON key is type
Name of file to load keystore from - note that some keystores, e.g. Luna does not have a file
Default: None
JSON key is file
Password for the keystore - can be encrypted, see Encrypting or Obfuscating Passwords
Default: None
JSON key is password
This is only needed if you have specific aliases in your keystore which have passwords that differ from the main keystore password - it allows you to specify a password for each alias specifically.
Default: None
JSON key is password.per.alias - this is a JSON Array with the format alias=password
If provided, only the private key with the specified alias will be loaded.
Default: None
JSON key is alias.privkey
If provided, only the certificate with the specified alias will be loaded
Default: None
JSON key is alias.cert
Allows you to provide the private key as an RSA key in PKCS#8 format by pasting it directly.
Default: None
JSON key is privatekey
Allows you to provide the certificate as Base64 encoded DER by pasting it directly instead of loading it from a keystore.
Default: None
JSON key is certificate
See also Keystore configuration for additional details of configuring keystores when issuing tokens. |
secret key, url and refresh interval are stored directly in the token JSON, the rest of the certificates in the JSON Object signer.certificates inside the token JSON.
Secret key, if token is signed with a shared secret key instead of a private key.
Default: None
JSON key is
Specify an URL, e.g. JWKS URL for where to load signed certificates from. Both standard JWKS, Googles and Microsoft proprietary formats are supported.
Default: None
JSON key is signer.certificates.url
Number of minutes between reloading certificates from the URL above.
Default: 60
JSON key is signer.certificates.refresh.interval.minutes
The following configuration for the certificates is stored in the JSON Object signer.certificates inside the token JSON.
Name of JCE provider - if left blank, platform default is used. Can be set to e.g. Luna to support hardware crypto providers assuming Luna JCE provider is installed.
Default: None
JSON key is provider
Provide a list of filenames or certificates directly within the configuration.
This allows you to specify additional trusted signer certificates for use when validating signed SAML Response - note that if you already are loading federation metadata from online, or have it pasted, these certificates configured here are in addition to the ones from the metadata.
Default: None
JSON key is certificates - which is a JSON Array of strings, each containing a filename of a certificate in .cer (binary or base64 encoded), .der or .p7b format or the certificate itself, if starting with -----BEGIN CERTIFICATE-----
See also Keystore configuration for additional details of configuring keystores |
The SSL settings are used when loading certificates from remote, the settings are stored in the JSON object ssl inside the token JSON object.
Uncheck to disable SSL server certificate validation - if checked, SSL server certificates must either match installed root certificates in the JVM, or one of the additionally specified certificates.
Default: true
JSON key is verify.server.cert
Uncheck to disable SSL hostname verification - if checked, the SSL hostname is matched up against the SSL server certificate.
Default: true
JSON key is verify.hostname
Name of JCE provider - if left blank, platform default is used. Can be set to e.g. Luna to support hardware crypto providers assuming Luna JCE provider is installed.
Default: None
JSON key is provider - inside accepted.certificates JSON object within the ssl object.
Provide a list of filenames or certificates directly within the configuration.
This allows you to specify additional SSL server issuer trust certificates certificates for use when validating signed SSL server certificate when retrieving metadata from remote
Default: None
JSON key is certificates- inside accepted.certificates JSON object within the ssl object.
Scopes are used to define which fields end up in which token - here you can specify that if a client asks for e.g. a scope called "salary" when requesting a token, then you control which attributes are added to the ID token, Access Token and Userinfo respectively.
This gives you fine grained control of which data you expose under which conditions.
Scopes are stored in a JSON Array called openid.scopes - each scope definition is a single JSON Object within this array.
"openid.scopes": [ { "name": "email", "description": "Email address in userinfo", "idtoken": ["email=email1"], "accesstoken": [], "userinfo": ["email=email1"] }, { "name": "profile", "description": "User name", "idtoken": ["name=username"], "accesstoken": ["name=username"], "userinfo": ["name=username"] } ] |
Scope name, must match the name used by the client/partner - e.g. "openid", "profile" or "email".
See https://openid.net/specs/openid-connect-core-1_0.html#ScopeClaims for a list of standard scope names part of the OpenID Connect standard.
Default: None
JSON key is name
Description of this scope - only for informational use.
Default: None
JSON key is description
List of attributes/claim to append to ID Token for this scope.
See SAML / JWT Attributes / Claims for details about the keys/values.
Default: None
JSON key is idtoken as a JSON Array of strings
List of attributes/claim to append to Access Token for this scope.
See SAML / JWT Attributes / Claims for details about the keys/values.
Default: None
JSON key is accesstoken as a JSON Array of strings
List of attributes/claim to append to userinfo endpoint for this scope.
See SAML / JWT Attributes / Claims for details about the keys/values.
Default: None
JSON key is userinfo as a JSON Array of strings
These configuration values are stored as a JSON Array called openid.fields present within the federation object.
"openid.fields": [{ "name": "address", "description": "User address", "attributes": [ "street_address=address1", "locality=city", "region=state", "postal_code=postal", "country=country" ] }] |
Some attributes are themselves objects, such as the OpenID Connect "address" object - by configuring them here, you control which attributes are included, and from where the information within originates.
So, in other words - this is where you specify objects that contain nested attributes.
A single Field definition looks like this:
Specify the attribute name, e.g. Address
Default: None
JSON key is name
Optional description for informatilnal purposes.
Default: None
JSON key is description
Attributes to add to this field.
See SAML / JWT Attributes / Claims for details about formats and values.
Default: None
JSON key is attributes - as a JSON Array containing string values
When Ceptor authenticates users using foreign OpenID Connect Providers, you can define the authentication providers here.
These Identity Providers are then used within the Ceptor Gateway - see Location - Authentication for information about how to configure the gateway to use these identity providers under specific conditions.
Ceptor has custom support for some identity providers which almost are following the OpenID Connect standard, such as LinkedIn and Facebook.
Configuration for identity providers are stored in a JSON Array called openid.identityproviders - each identity provider is a separate JSON Object.
"openid.identityproviders": [ { "name": "facebook", "description": "Authenticate using facebook", "clientid": "624082557774373", "secret": "{encoded}F89141217749F5FA6306CAF6F9656965F3A5A8E3069BE032136125F3A4B27183", "tokenurl": "https://graph.facebook.com/v2.9/oauth/access_token", "facebook": true, "linkedin": false, "fieldmappers": [] }, { "name": "google", "description": "Google as an identity provider", "clientid": "371213948273-79eceu24cm64ft69pln0hk2lfapok1bq.apps.googleusercontent.com", "secret": "{encoded}806F9FE0C7CBC28D5777D6DE91772DA4961482568956695A", "tokenurl": "https://accounts.google.com/o/oauth2/token", "facebook": false, "linkedin": false, "fieldmappers": [] }, { "name": "microsoft", "description": "Authenticate using microsoft as identity provider", "clientid": "317190f9-efec-4307-beb9-7f8380a8ae16", "secret": "{encoded}9EED6C32369008FE6F3DC027CC0C2195137300594A2620", "tokenurl": "https://login.microsoftonline.com/common/oauth2/v2.0/token", "facebook": false, "linkedin": false, "fieldmappers": [] } ] |
Identity provider name
Default: None
JSON key is name
Optional description - used for informational purposes only.
Default: None
JSON key is description
Client ID - used together with the OAuth2 Authorization code flow to obtain a token from the identity provider.
Default: None
JSON key is clientid
Client secret.
Default: None
JSON key is secret
Identity Provider Token URL - called to exchange the authorization code for a token.
Default: None
JSON key is tokenurl
Check if Identity Provider is Facebook - Facebook has its own special interface.
Default: false
JSON key is facebook
Comma separated list of fields to read from facebook
Default: id,cover,name,first_name,last_name,age_range,link,gender,locale,picture,timezone,updated_time,verified
JSON key is facebookfields
URL to facebook provider Graph API - required since Facebook is not really OpenID Connect compliant but has its own twist
Default: https://graph.facebook.com/me
JSON key is name
Check to enable special handling for using Linkedin as an identity provider, since it is not fully OpenID Connect compliant
Default: false
JSON key is linkedin
Comma separated list of fields to read from linkedin
Default: id,firstName,lastName,headline,num-connections,picture-url,formatted-name,summary,location,public-profile-url
JSON key is linkedinfields
URL to linkedin API
Default: https://api.linkedin.com/v1/people/~
JSON key is linkedinurl
Allows customized mapping of attribute values.
Each attribute is stored as a JSON object with key and value attributes inside it.
Key is one of:
The value is a string, where macros are replaced with the appropriate contents - a macro can be %{claim:XXXX
} where XXXX is the name of a claim key in the JSON JWT token, or token returned from an identity provider such as facebook.
Macros are in the form %{type:name} where type can be claim, base64, urlencode, htmlencode, base64decode, urldecode - the default is claim if not specified. If set to e.g. base64, the value will be treated as base64 and decoded.
Like with Ceptor Gateway - Scripts and Macros you can use scripts (javascript, python or groovy) and %{rewrite} macros to do more advanced transformations of values. When scripts are used, the variable context will point to an object which contains two variables; session pointing to the users Ceptor Session, and jo pointing to a JSONObject containing the claims to map.
Examples:
%{claim:firstName} %{claim.lastName} %{script}salary(); function salary() {var json = JSON.from(context.jo.toJSONString()); return (json.monthlySalary * 12) + json.yearlyBonus;} |
Default: None
JSON key is fieldmappers
Normally, you would configure partners as part of API Management here: Managing Partners, Applications and Developers - but in smaller installations where you use "dk.itp.security.authentication.oauth.data.properties.OAuth2DataStoreProperties" as OAuth2 datastore implementation, you can configure the clients or partners here.
OAuth2 Clients/Partners are stored in a JSON Array called oauth2.clients - each client definition is a JSON object.
"oauth2.clients": [{ "name": "Sample", "client_id": "https://www.example.com/", "description": "Example client", "client_secret": "secret", "accesstoken_type": "UUID", "allowed_uris": ["https://www.example.com/oauth2"], "allowed_logout_uris": [], "valid_grant_types": [ "authorization_code", "implicit", "hybrid", "refresh_token" ], "allowed_scopes": [ "openid", "profile", "offline_access" ], "refreshtoken_validity_seconds": 86400, "maximum_idtoken_expiration_minutes": 120 }] |
Name of OAuth 2 / OpenID Connect client or partner.
Default: None
JSON key is name
Optional description
Default: None
JSON key is description
Client ID - must be unique across all configured clients.
Default: None
JSON key is client_id
Client secret - may be encrypted/obfuscated.
Default: None
JSON key is client_secret
Type of access token to issuer - either UUID or JWT/RFC9068/RFC9068UP - if UUID, the token itself does not contain any attributes, and the OAuth2 introspection (or userinfo) URL must be called using the access token to get any of the attributes related to it. If the type is JWT, the access token is similar to the ID token a signed JWT token containing the attributes itself.
For JWT tokens, RFC9068 / RFC9068UP are variants of JWT tokens where they set the "typ" header value to "at-jwt" or "at-JWT" respectively.
RFC 9068 (see https://www.rfc-editor.org/rfc/rfc9068.html) mentions in the textual description and registration section that the type must be set to "at-jwt" but the examples within it set it to "at-JWT" with JWT in uppercase. Since some client might care about the case, you can select the type RFC9068 for the lowercase version, but also RFC9068UP for the uppercase version used in the examples. |
Default: UUID
JSON key is accesstoken_type
Name of token to use if not the default -allows you to select specific tokens (and thus specific keys, content etc.) for specific clients.
Default: None
JSON key is tokenname
List of valid redirect URIs for this client/partner
Default: None
JSON key is allowed_uris as a JSON array of strings
List of valid logout URIs for this client/partner
Default: None
JSON key is allowed_logout_uris as a JSON array of strings
List of valid grant types to allow for this client. If this list is empty, all types are allowed, otherwise only the specified ones are allowed for this client to use.
Default: None
JSON key is valid_grant_types
If not empty, this list restricts which scope names the client is allowed to use.
Default: None
JSON key is allowed_scopes as a JSON array of strings
If specified, can override the default validity period of issued access tokens.
Default: None
JSON key is accesstoken_valid_seconds
If specified, can override the default validity period of issued refresh tokens.
Default: None
JSON key is refreshtoken_validity_seconds
If specified, can override the default validity period of issued ID tokens.
Default: None
JSON key is maximum_idtoken_expiration_minutes