swagger: '2.0'
info:
x-ibm-name: oauth2-oidc-provider
title: OAuth2 OIDC Provider
version: 1.0.0
description: >-
Provide a template on how to enable OIDC for APIC OAuth provider.
Authorization Code : the standard OAuth protocol
Resource Owner Grant Type : the 2 legged owner grant type
Client Credential : there is no user in this, and thus no id_token will be
created
Skip:
Implicit : this is a subset of authorization code grant type, public client
contact:
url: 'https://www.ibm.com/support/home/product/I433959L64023U66/IBM_API_Connect'
name: IBM
schemes:
- https
host: $(catalog.host)
basePath: /
securityDefinitions:
clientID:
description: application's client_id
in: query
name: client_id
type: apiKey
clientIdHeader:
in: header
type: apiKey
name: X-IBM-Client-Id
clientSecretHeader:
in: header
type: apiKey
name: X-IBM-Client-Secret
security:
- clientID: []
paths:
/oauth2/authorize:
get:
produces:
- text/html
summary: endpoint for Authorization Code and Implicit grants
description: description
parameters:
- name: response_type
in: query
description: request an authorization code or or access token (implicit)
required: true
type: string
enum:
- code
- token
- name: scope
in: query
description: Scope being requested
type: string
required: true
- name: redirect_uri
in: query
type: string
description: URI where user is redirected to after authorization
required: false
- name: state
in: query
type: string
description: >-
This string will be echoed back to application when user is
redirected
required: false
responses:
'200':
description: An HTML form for authentication or authorization of this request.
'302':
description: >
Redirect to the clients redirect_uri containing one of the following
- **authorization code** for Authorization code grant
- **access token** for Implicity grant
- **error** in case of errors, such as the user has denied the
request
security:
- clientID: []
post:
consumes:
- application/x-www-form-urlencoded
produces:
- text/html
summary: submit approval to authorization code or access token
description: >
Submit resource owners approval (or rejection) for the OAuth2 Server to
issue an
authorization code or access token to the application.
security: []
parameters:
- name: client_id
in: formData
description: application requesting the access code or token
required: true
type: string
- name: scope
in: formData
description: requested scope of this authorization
required: true
type: string
- name: resource-owner
in: formData
description: resource owners user name
required: true
type: string
- name: redirect_uri
in: formData
description: >-
URI the application is requesting this code or token to be
redirected to
required: true
type: string
- name: original-url
in: formData
description: URL of the original authorization request
required: true
type: string
- name: dp-state
in: formData
description: state information provided in the authorization form
required: true
type: string
- name: dp-data
in: formData
description: state information provided in the authorization form
required: true
type: string
responses:
'200':
description: Cool
/oauth2/token:
post:
consumes:
- application/x-www-form-urlencoded
produces:
- application/json
summary: Request Access Tokens
description: >
This endpoint allows requesting an access token following one of the
flows below:
- Authorization Code (exchange code for access token)
- Client Credentials (2-legged, there isnt resource owner information)
- Resource Owner Password Credentials (2-legged, client provides
resource owner name and password)
- Refresh Token (exchange refresh token for a new access code)
The table below indicates the required parameters for each specific
grant_type options.
Empty cells indicate a parameter is ignored for that specific grant
type.
Client authentication:
- Confidential clients should authenticate using HTTP Basic
Authentication. Alternatively, they may post
their client_id and client_secret information as a formData parameter.
- Public clients should send their client_id as formData parameter.
| grant_type | code | client_credentials | password |
refresh_token |
|----------------------|------------|--------------------|-------------|---------------|
| client_id | required* | required* | required* |
required* |
| client_secret | required* | required* | required* |
required* |
| code | required | |
| |
| redirect_uri | required | |
| |
| username | | | required
| |
| password | | | required
| |
| scope | | optional | optional
| |
| refresh_token | | | |
required |
The implicit grant requests, see /oauth2/authorize.
security: []
parameters:
- name: grant_type
in: formData
description: Type of grant
type: string
required: true
enum:
- authorization_code
- password
- client_credentials
- refresh_token
- name: client_id
in: formData
description: >-
Application client ID, can be provided in formData or using HTTP
Basic Authentication
required: false
type: string
- name: client_secret
in: formData
description: >-
Application secret, must be provided in formData or using HTTP Basic
Authentication
required: false
type: string
- name: code
in: formData
description: Authorization code provided by the /oauth2/authorize endpoint
required: false
type: string
- name: redirect_uri
in: formData
description: >-
required only if the redirect_uri parameter was included in the
authorization request /oauth2/authorize; their values MUST be
identical.
required: false
type: string
- name: username
in: formData
type: string
description: Resource owner username
required: false
- name: password
in: formData
type: string
description: Resource owner password
required: false
- name: scope
in: formData
type: string
description: Scope being requested
required: false
- name: refresh_token
in: formData
type: string
description: >-
The refresh token that the client wants to exchange for a new access
token (refresh_token grant_type)
required: false
responses:
'200':
description: 'json document containing token, etc.'
schema:
$ref: '#/definitions/access_token_response'
'400':
description: json document that may contain additional details about the failure
/oauth2/revoke:
post:
consumes:
- application/x-www-form-urlencoded
summary: Introspect a given access_token supported
description: |
This endpoint introspects a given access_token
security:
- clientIdHeader: []
clientSecretHeader: []
parameters:
- name: token
in: formData
description: 'String value of the access_token, or refresh_token to be revoked'
required: true
type: string
- name: token_type_hint
in: formData
description: >-
This must contain 'access_token' or 'refresh_token' to indicate the
token type
required: true
type: string
responses:
'200':
description: not applicable
/oauth2/introspect:
post:
consumes:
- application/x-www-form-urlencoded
produces:
- application/json
summary: Introspect a given access_token supported
description: |
This endpoint introspects a given access_token
security:
- clientIdHeader: []
clientSecretHeader: []
parameters:
- name: token
in: formData
description: String value of the access_token to be introspected
required: true
type: string
- name: token_type_hint
in: formData
description: This must contain 'access_token' to indicate the token type
required: true
type: string
responses:
'200':
description: 'json document containing issued information, etc.'
schema:
$ref: '#/definitions/introspect_response'
'401':
description: failure
/oauth2/issued:
get:
produces:
- application/json
summary: Returns list of permission granted to the owner
description: >
This endpoint allows the return of all the issued permission for a given
authenticated owner per owner authentication
defined in the x-ibm-configuration section
security:
- clientIdHeader: []
clientSecretHeader: []
responses:
'200':
description: 'json document containing issued information, etc.'
schema:
$ref: '#/definitions/issued_responses'
'401':
description: failure in retreiving issued list
delete:
consumes:
- application/x-www-form-urlencoded
produces:
- application/json
summary: Revoke an application/client permission by the authorized owner
description: Revoke an application/client permission by the authorized owner
security:
- clientIdHeader: []
clientSecretHeader: []
parameters:
- name: client-id
in: query
description: client-id is the OAuth client_id or application id to be revoked
required: true
type: string
responses:
'200':
description: OK
x-ibm-configuration:
testable: true
enforced: true
phase: realized
oauth2:
client-type: confidential
scopes:
weather: Weather Information
openid: Enable OIDC
grants:
- password
- accessCode
- application
- implicit
identity-extraction:
type: basic
authentication:
x-ibm-authentication-url:
url: 'https://$(api.endpoint.address):9443/utility/basic-auth/spoon/spoon'
tls-profile: ''
authorization:
type: authenticated
access-token:
ttl: 3600
refresh-token:
count: 2048
ttl: 2682000
gateway: datapower-gateway
assembly:
execute:
- set-variable:
title: set-variable
actions:
- set: iss.claim
value: $(OIDCIssuer)
- set: sign-jwk
value: $(JWSSignPrivateKey)
- set: jwt.sign.algorithm
value: $(JWSAlgorithm)
- set: oidc.custom.claim
value: '{"disclaimer":"For OpenBanking OIDC demo purpose"}'
version: 1.0.0
- switch:
title: switch
case:
- condition: >-
(((request.verb==='GET')&&(api.operation.path==='/oauth2/authorize'))||((request.verb==='POST')&&(api.operation.path==='/oauth2/authorize'))
&& new String (apim.getvariable
('message.status.code')).startsWith ('302'))
execute:
- xslt:
title: xslt
input: false
version: 1.0.0
source: >-
- condition: >-
((request.verb==='POST')&&(api.operation.path==='/oauth2/token'))
execute:
- gatewayscript:
title: gatewayscript
version: 1.0.0
source: >-
let _apimgmt = session.name('_apimgmt');
let grantType = _apimgmt.getVariable('requested-grant-type');
if (grantType === 'password' || grantType === 'code') {
// get scope
var splitScope = (apim.getvariable('message.body').scope || '').split(' ');
if (splitScope.length === 0) {
var vScopeNode = session.name('INPUT').getVariable('oauth/verified-scope').item(0).childNodes;
if (vScopeNode !== undefined && vScopeNode !== null) {
let vScope = vScopeNode.item(0).textContent;
splitScope = vScope.split(' ');
}
}
for (let i = 0; i < splitScope.length; i++) {
if (splitScope[i] === 'openid') {
let userIdentity = _apimgmt.getVariable('authenticated-username');
apim.setvariable('oidc-credential', userIdentity, 'set');
}
}
}
version: 1.0.0
- if:
title: if
condition: apim.getvariable('oidc-credential') !== undefined
execute:
- xslt:
title: xslt
input: false
version: 1.0.0
source: >-
{
"c_hash":"
"
"at_hash":"
"
,
"s_hash":"
"
,
"s_hash":"
"
,
"nonce":"
"
,
"custom_attribute":"
"
}
- jwt-generate:
title: jwt-generate
iss-claim: iss.claim
exp-claim: 3600
version: 1.0.0
jwt: idtoken
jti-claim: true
sub-claim: oidc-credential
aud-claim: client.app.id
private-claims: added.claim
jws-alg: RS256
jws-jwk: sign-jwk
- gatewayscript:
title: gatewayscript
version: 1.0.0
source: >-
let grantType =
session.name('_apimgmt').getVariable('requested-grant-type');
if (grantType === 'implicit') {
// regression in 5070 will not allow access, and modification to the location header
let location = apim.getvariable('oidc-location') + '&id_token=' + apim.getvariable("idtoken");
// work around is to use xslt
apim.setvariable('oidc-location', location);
}
else {
if (apim.getvariable('oidc-location') !== undefined && apim.getvariable('oidc-location').indexOf('code=') !== -1) {
let location = apim.getvariable('oidc-location') + '&id_token=' + apim.getvariable("idtoken");
apim.setvariable('oidc-location', location);
}
else {
let token = apim.getvariable("message.body");
token["id_token"] = apim.getvariable("idtoken");
apim.setvariable("message.body", JSON.stringify(token));
}
}
- if:
title: if
condition: >-
new String
(apim.getvariable('message.status.code')).startsWith('302')
execute:
- xslt:
title: xslt
input: false
version: 1.0.0
source: >
version: 1.0.0
version: 1.0.0
catch: []
properties:
JWSSignPrivateKey:
value: >-
{ "kty": "RSA", "d":
"ZgiybjfeIsoihPMRQpT9Yv5Qfvg5AaqdGRK8mb1G73_CrOjpTbXjs7t0AKKNTGFUlvla4ag9kof4qzA7EB0Kgpsn05668sQtenIkz83pP1v7MaM31YovGq1WCmCpV8lJvuaSAP06ueRmEYG5zhtT9lK3TVxvuYwCd_Ukfe0M3R3ajyLEvPLhnwS5mybAj0mP5lat1l29qXhC-WNhDRZfl6NdVge4yGyKLsNAXqWw0bi3ARE3dYPt7J36cqoET4agwOjjupxY8Ctv1tFw7Xj3lcUBciT_tYi3tKVs8ALalTQ-MHOXHEdDXaAxzgmLVgFD05bbE55OL25MLSvoD0bLAQ",
"e": "AQAB", "use": "sig", "kid": "spoon", "alg": "RS256", "n":
"iE7cj97VkW-QXXU0U9Fedjl7digjnp_R7lx6LHLugHfS5Xp26GCxOO1pNktSHsfof5EMJ0y8iqtIH4X3QYLg6E6fEZQD4-ZpIaKhTDuel1Zls_NRFgrQ0gzB3oiNJbNMfbNLpx4hCauRRv_RqRb1__jkBRIiU3MrEmB6gBDBQYJ9vwcYDXT5qowAopoZk6p1bf6kftMswVoFsILt9XdBynTHcLPyj61mP0faUb5_VRkpXaCbyCn4G1XakKswqzSkULImNQykaK_I6IJ0CGI0gnnx5YmwNbo4AYS-8fDODXfThDZC12TM_BlCGQMAao2jSSXaebI1nyxmgaYV1oChbw"
}
description: ''
encoded: false
OIDCIssuer:
value: IBM APIc
description: ''
encoded: false
JWSAlgorithm:
value: RS256
description: ''
encoded: false
definitions:
access_token_response:
type: object
additionalProperties: false
required:
- token_type
- access_token
- expires_in
properties:
token_type:
enum:
- bearer
access_token:
type: string
expires_in:
type: integer
scope:
type: string
refresh_token:
type: string
introspect_response:
type: object
additionalProperties: false
required:
- active
- client_id
- client_name
- username
- sub
- exp
- expstr
- iat
- nbf
- nbfstr
- scope
properties:
active:
type: boolean
client_id:
type: string
client_name:
type: string
username:
type: string
sub:
type: string
exp:
type: string
expstr:
type: string
iat:
type: string
nbf:
type: string
nbfstr:
type: string
scope:
type: string
miscinfo:
type: string
consented_on:
type: string
consented_on_str:
type: string
grant_type:
type: string
issued_response:
type: object
additionalProperties: false
required:
- clientId
- owner
- scope
- issuedAt
- expiredAt
- refreshTokenIssued
properties:
clientId:
type: string
clientName:
type: string
owner:
type: string
scope:
type: string
issuedAt:
type: string
expiredAt:
type: string
refreshTokenIssued:
type: boolean
miscInfo:
type: string
consentedOn:
type: string
appId:
type: string
org:
type: string
orgId:
type: string
catalog:
type: string
catalogId:
type: string
issued_responses:
type: array
items:
$ref: '#/definitions/issued_response'
externalDocs:
url: >-
https://www.ibm.com/support/knowledgecenter/SSMNED_5.0.0/com.ibm.apic.toolkit.doc/tapic_sec_api_config_oidc.html
description: Securing your APIs with OpenID Connect