Authorization Code
This is a service that supports authorization code grant type. The authorization code grant type is used to obtain both access tokens and refresh tokens and is optimized for confidential clients. Since this is a redirection-based flow, the client must be capable of interacting with the resource owner’s user-agent (typically a web browser) and capable of receiving incoming requests (via redirection) from the authorization server.
The service accepts user credentials and redirects back authorization code with redirect URI defined in the client registration or overwritten it by passing in a redirect URI in the request.
Request
The client constructs the request URI by adding the following parameters to the query component of the authorization endpoint URI using the “application/x-www-form-urlencoded” format.
- response_type
REQUIRED. The value MUST be set to “code”.
- client_id
REQUIRED. The client identifier.
- redirect_uri
OPTIONAL. Redirect URI.
- scope
OPTIONAL. The scope of the access request. The client’s default scope will be used if this value is not passed in.
- state
RECOMMENDED. An opaque value used by the client to maintain state between the request and callback. The authorization server includes this value when redirecting the user-agent back to the client. The parameter SHOULD be used for preventing cross-site request forgery.
- code_challenge
OPTIONAL. PKCE Code challenge. Required for Mobile Native Appilication
- code_challenge_method
OPTIONAL. S256 or plain if the platform doesn’t support S256.
- user_type
OPTIONAL. used to trigger different authentication providers based on the user type.
- roles
OPTIONAL. User roles concat with a space for fine-grained authorization.
Authorization Response
If the resource owner grants the access request, the authorization server issues an authorization code and delivers it to the client by adding the following parameters to the query component of the redirection URI using the “application/x-www-form-urlencoded” format.
- code
REQUIRED. The authorization code generated by the authorization server. The authorization code MUST expire shortly after it is issued to mitigate the risk of leaks. A maximum authorization code lifetime of 10 minutes is RECOMMENDED. The client MUST NOT use the authorization code more than once. If an authorization code is used more than once, the authorization server MUST deny the request and SHOULD revoke (when possible) all tokens previously issued based on that authorization code. The authorization code is bound to the client identifier and redirection URI.
- state
REQUIRED if the “state” parameter was present in the client authorization request. The exact value received from the client.
Error Response
If the request fails due to a missing, invalid, or mismatching redirection URI, or if the client identifier is missing or invalid, the authorization server SHOULD inform the resource owner of the error and MUST NOT automatically redirect the user-agent to the invalid redirection URI.
If the resource owner denies the access request or if the request fails for reasons other than a missing or invalid redirection URI, the authorization server informs the client by adding the following parameters to the query component of the redirection URI using the “application/x-www-form-urlencoded” format.
error
REQUIRED. A single ASCII [USASCII] error code from the following:
- invalid_request
The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed.
- unauthorized_client
The client is not authorized to request an authorization code using this method.
- access_denied
The resource owner or authorization server denied the request.
- unsupported_response_type
The authorization server does not support obtaining an authorization code using this method.
- invalid_scope
The requested scope is invalid, unknown, or malformed.
- server_error
The authorization server encountered an unexpected condition that prevented it from fulfilling the request.
(This error code is needed because a 500 Internal Server Error HTTP status code cannot be returned to the client via an HTTP redirect.)
- temporarily_unavailable
The authorization server is currently unable to handle the request due to a temporary overloading or maintenance of the server. (This error code is needed because a 503 Service Unavailable HTTP status code cannot be returned to the client via an HTTP redirect.)
Values for the “error” parameter MUST NOT include characters outside the set %x20-21 / %x23-5B / %x5D-7E.
error_description
OPTIONAL. Human-readable ASCII [USASCII] text providing additional information, used to assist the client developer in understanding the error that occurred.
Values for the “error_description” parameter MUST NOT include characters outside the set %x20-21 / %x23-5B / %x5D-7E.
error_uri
OPTIONAL. A URI identifying a human-readable web page with information about the error used to provide the client developer with additional information about the error.
Values for the “error_uri” parameter MUST conform to the URI-reference syntax and thus MUST NOT include characters outside the set %x21 / %x23-5B / %x5D-7E.
state
REQUIRED if a “state” parameter was present in the client authorization request. The exact value received from the client.
Implementation
There are two endpoints and the service default listening port is 6881.
Here is the specification:
swagger: '2.0'
info:
version: "1.0.0"
title: OAuth2 Service Authorization Code
description: OAuth2 Service that logs in user and provide authorization code.
contact:
email: [email protected]
license:
name: "Apache 2.0"
url: "http://www.apache.org/licenses/LICENSE-2.0.html"
host: oauth2.networknt.com
schemes:
- http
- https
consumes:
- application/json
produces:
- application/json
paths:
/oauth2/code:
get:
description: Return 302 redirect with authorization code
operationId: getAuthCode
parameters:
- name: "Authorization"
description: "encoded username:password mandatory if Basic Authentication is used"
in: "header"
required: false
type: "string"
- name: "response_type"
in: "query"
description: "The response type for authorization code"
required: true
type: "string"
enum:
- "code"
- name: "client_id"
in: "query"
description: "The client id for authorization code"
required: true
type: "string"
- name: "redirect_uri"
in: "query"
description: "The redirect uri for authorization code"
required: false
type: "string"
- name: "username"
in: "query"
description: "The user name for authorization code"
required: false
type: "string"
- name: "password"
in: "query"
description: "The password for authorization code in clear text"
required: false
type: "string"
- name: "user_type"
in: "query"
description: "The type of user that drives authentication and authorization"
required: false
type: "string"
- name: "roles"
in: "query"
description: "User roles concat with a space for fine-grained authorization"
required: false
type: "string"
- name: "state"
in: "query"
description: "to prevent cross-site request forgery"
required: false
type: "string"
- name: "scope"
in: "query"
description: "scope of the request"
required: false
type: "string"
- name: "code_challenge"
in: "query"
description: "PKCE code challenge"
required: false
type: "string"
- name: "code_challenge_method"
in: "query"
description: "PKCE code challenge method"
required: false
type: "string"
responses:
302:
description: "Successful Operation"
post:
description: Return 302 redirect with authorization code
operationId: postAuthCode
consumes:
- "application/x-www-form-urlencoded"
produces:
- "application/json"
parameters:
- name: "j_username"
in: "formData"
description: "User name"
required: true
type: "string"
- name: "j_password"
in: "formData"
description: "Password"
required: true
type: "string"
- name: "response_type"
in: "formData"
description: "Response type"
required: true
type: "string"
enum:
- "code"
- name: "client_id"
in: "formData"
description: "Client Id"
required: true
type: "string"
- name: "redirect_uri"
in: "formData"
description: "Redirect Uri"
required: false
type: "string"
- name: "state"
in: "formData"
description: "to prevent cross-site request forgery"
required: false
type: "string"
- name: "scope"
in: "formData"
description: "scope of the request"
required: false
type: "string"
- name: "code_challenge"
in: "formData"
description: "PKCE code challenge"
required: false
type: "string"
- name: "code_challenge_method"
in: "formData"
description: "PKCE code challenge method"
required: false
type: "string"
responses:
302:
description: "Successful Operation"
/oauth2/code@get
The get endpoint is the most used as it is very simple and supported by all browsers without any customization. When request is received by the service, the following validations or processes are done before issuing an authorization code redirect.
If SPNEGO/Kerberos is supported on the user’s operating system and there is no authorization header send to the light-oauth2 code service, then the code service will try to negotiate with the user agent to get a Kerberos ticket. If there is no proper response from the user agent, then fall back to basic authentication described below. Please refer to SPNEGO/Kerberos for more info.
If SPNEGO/Kerberos is not implemented, then the code service falls back to basic authentication. Make sure that user credentials are passed in if you want to skip the SPNEGO/Kerberos. Otherwise, SPNEGO will always be tried first. If the browser doesn’t support SPNEGO, the code service will redirect the browser to display a popup window to collect userId and password. The username and password will be passed in as Basic Authorization header. The passed in userId and password will be matched with a cached password(which is hashed and salted). If userId and password combination is not valid, then a brand new popup window will be shown. Depending on browsers, an error message will be shown up after several times of retries.
If the password is incorrect, then the following error will return.
"ERR12016": {
"statusCode": 401,
"code": "ERR12016",
"message": "INCORRECT_PASSWORD",
"description": "Incorrect password."
}
- Make sure that response_type and client_id are passed in as parameters. If not, the following error will be returned.
"ERR11000": {
"statusCode": 400,
"code": "ERR11000",
"message": "VALIDATOR_REQUEST_PARAMETER_QUERY_MISSING",
"description": "Query parameter '%s' is required on path '%s' but not found in request."
}
- If response_type doesn’t equal “code” then the following error will return
"ERR11004": {
"statusCode": 400,
"code": "ERR11004",
"message": "VALIDATOR_SCHEMA",
"description": "Schema Validation Error - %s"
}
- Make sure client_id passed in is valid again in memory client cache. If not, then the following error will be returned.
"ERR12014": {
"statusCode": 404,
"code": "ERR12014",
"message": "CLIENT_NOT_FOUND",
"description": "Client %s is not found."
}
- As you can see from the specification, there is an optional parameter called redirect_uri. If this parameter is passed in, it will be used to redirect the authorization code. Otherwise, the default redirect_uri from client_id will be used. This is retrieved from the in-memory client cache. The URL is populated when the client is registered during the on-boarding process.
/oauth2/code@post
To be completed later