Authorization Code Handler

AuthorizationCodeHandler is the authentication handler used for OpenID Connect authorization code flow.

Overview

Config yaml format becomes like below. And the resource specific spec is defined in in the proto format shown in the Resource Definition.

apiVersion: app/v1
kind: AuthorizationCodeHandler
metadata:
  name: "default"
  namespace: "default"
spec: {}

Resource Definition

AuthorizationCodeHandler is defined in the proto/app/v1/authn/oauth.proto

  1syntax = "proto3";
  2package app.v1;
  3
  4import "app/v1/jwt.proto";
  5import "buf/validate/validate.proto";
  6import "kernel/resource.proto";
  7
  8option go_package = "github.com/aileron-gateway/aileron-gateway/apis/app/v1";
  9
 10// OAuthAuthenticationHandler resource definition.
 11// apiVersion="app/v1", kind="OAuthAuthenticationHandler".
 12message OAuthAuthenticationHandler {
 13    string                         APIVersion = 1 [json_name = "apiVersion"];
 14    string                         Kind       = 2 [json_name = "kind"];
 15    kernel.Metadata                Metadata   = 3 [json_name = "metadata"];
 16    OAuthAuthenticationHandlerSpec Spec       = 4 [json_name = "spec"];
 17}
 18
 19// OAuthAuthenticationHandlerSpec is the specifications for the OAuthAuthenticationHandler object.
 20message OAuthAuthenticationHandlerSpec {
 21    // [OPTIONAL]
 22    // Logger is the reference to a Logger object.
 23    // Referred object must implement Logger interface.
 24    // Default Logger is used when not set.
 25    kernel.Reference Logger = 1 [json_name = "logger"];
 26
 27    // [OPTIONAL]
 28    // ErrorHandler is the reference to a ErrorHandler object.
 29    // Referred object must implement ErrorHandler interface.
 30    // Default error handler is used when not set.
 31    kernel.Reference ErrorHandler = 2 [json_name = "errorHandler"];
 32
 33    // [REQUIRED]
 34    // Contexts is the authentication context.
 35    // This field is optional but should be set at least 1 context
 36    // to make authentication work.
 37    // Default is not set.
 38    repeated Context Contexts = 3 [json_name = "contexts"];
 39
 40    // [OPTIONAL]
 41    // ClaimsKey is the key to save claims in the context and make it usable
 42    // from authorization middleware.
 43    // Default is not set.
 44    string ContextQueryKey = 4 [json_name = "contextQueryKey"];
 45
 46    // [OPTIONAL]
 47    // ClaimsKey is the key to save claims in the context and make it usable
 48    // from authorization middleware.
 49    // Default is not set, or empty .
 50    string ContextHeaderKey = 5 [json_name = "contextHeaderKey"];
 51
 52    // [REQUIRED]
 53    // Handlers are the options of OAuth authentication handlers.
 54    oneof Handlers {
 55        option(buf.validate.oneof).required               = true;
 56        AuthorizationCodeHandler AuthorizationCodeHandler = 10 [json_name = "authorizationCodeHandler"];
 57        ClientCredentialsHandler ClientCredentialsHandler = 11 [json_name = "clientCredentialsHandler"];
 58        ResourceServerHandler    ResourceServerHandler    = 12 [json_name = "resourceServerHandler"];
 59        ROPCHandler              ROPCHandler              = 13 [json_name = "ropcHandler"];
 60    }
 61}
 62
 63// ProviderEndpoints is the endpoints of OAuth provider.
 64message ProviderEndpoints {
 65    string Authorization = 1 [json_name = "authorization"];
 66    string Token         = 2 [json_name = "token"];
 67    string Userinfo      = 3 [json_name = "userinfo"];
 68    string Introspection = 4 [json_name = "introspection"];
 69    string Revocation    = 5 [json_name = "revocation"];
 70    string JWKs          = 6 [json_name = "jwks"];
 71    string Discovery     = 7 [json_name = "discovery"];
 72}
 73
 74// OAuthProvider is the configuration of OAuth provider.
 75message OAuthProvider {
 76    string            Issuer       = 1 [json_name = "issuer"];
 77    string            BaseURL      = 2 [json_name = "baseURL"];
 78    ProviderEndpoints Endpoints    = 3 [json_name = "endpoints"];
 79    kernel.Reference  RoundTripper = 4 [json_name = "roundTripper"];
 80}
 81
 82// OAuthClient is the configuration of OAuth client.
 83message OAuthClient {
 84    string          ID         = 1 [json_name = "id"];
 85    string          Secret     = 2 [json_name = "secret"];
 86    string          Audience   = 3 [json_name = "audience"];
 87    repeated string Scopes     = 4 [json_name = "scopes"];
 88    JWTHandlerSpec  JWTHandler = 5 [json_name = "jwtHandler"];
 89}
 90
 91// PKCEMethod is the PKCE code challenge methods.
 92// Method is defined in https://datatracker.ietf.org/doc/rfc7636/
 93enum PKCEMethod {
 94    S256  = 0;  // "S256"
 95    Plain = 1;  // "plain"
 96}
 97
 98// ClientAuthMethod is the method of authentication
 99// used for OAuth client authentication.
100enum ClientAuthMethod {
101    FormAuth                = 0;  // Form authentication
102    BasicAuth               = 1;  // Basic authentication
103    ClientSecretJWT         = 2;  // Authentication by JWT signed with a client secret
104    PrivateKeyJWT           = 3;  // Authentication by JWT signed with a client secret
105    TLSClientAuth           = 4;  // Authentication by PKI-based X.509 certificates
106    SelfSignedTLSClientAuth = 5;  // Authentication by self-signed X.509 certificates
107}
108
109message ClientRequester {
110    // [OPTIONAL]
111    // RoundTripper is the reference to a HTTP round tripper object.
112    // A default round trupper will be used when not set.
113    // Default is not set.
114    kernel.Reference RoundTripper = 1 [json_name = "roundTripper"];
115
116    // [OPTIONAL]
117    // ClientAuthMethod is the OAuth client authentication method.
118    // Form or Basic authentication is available for now.
119    // Default is [Form].
120    ClientAuthMethod ClientAuthMethod = 2 [json_name = "clientAuthMethod"];
121
122    // [OPTIONAL]
123    // ExtraHeader is the additional HTTP request headers
124    // set when request is sent by the client.
125    // Default is not set.
126    map<string, string> ExtraHeader = 3 [json_name = "extraHeader"];
127
128    // [OPTIONAL]
129    // ExtraQuery is the additional HTTP query parameters
130    // for form request body which is set when request is sent by the client.
131    // Default is not set.
132    map<string, string> ExtraQuery = 4 [json_name = "extraQuery"];
133}
134
135message Context {
136    // [REQUIRED]
137    // Provider is the configurations of OAuth provider.
138    string Name = 1 [json_name = "name"];
139
140    // [REQUIRED]
141    // Provider is the configurations of OAuth provider.
142    OAuthProvider Provider = 2 [json_name = "provider"];
143
144    // [REQUIRED]
145    // Client is the configurations of OAuth client.
146    OAuthClient Client = 3 [json_name = "client"];
147
148    // [OPTIONAL]
149    // TokenRedeemer is the configuration for token requests.
150    ClientRequester TokenRedeemer = 4 [json_name = "tokenRedeemer"];
151
152    // [OPTIONAL]
153    // TokenRedeemer is the configuration for token introspection requests.
154    ClientRequester TokenIntrospector = 5 [json_name = "tokenIntrospector"];
155
156    // [OPTIONAL]
157    // JWTHandler is the configuration for JWT handlers.
158    JWTHandlerSpec JWTHandler = 6 [json_name = "jwtHandler"];
159
160    // [OPTIONAL]
161    // EnableIntrospection
162    // If false, JWTs are validated locally
163    // Enabling both local validation and validation by introspection
164    // is not supported.
165    // Default is [false].
166    bool EnableIntrospection = 7 [json_name = "enableIntrospection"];
167
168    // [OPTIONAL]
169    // ClaimsKey is the key to save claims in the context and make it usable
170    // from authorization middleware.
171    // Default is ["AuthnClaims"].
172    string ClaimsKey = 8 [json_name = "claimsKey"];
173
174    // [OPTIONAL]
175    // ATProxyHeader is the header name to proxy access token if exists.
176    // Token is not proxied when the value is empty.
177    // Default is [""].
178    string ATProxyHeader = 9 [json_name = "atProxyHeader"];
179
180    // [OPTIONAL]
181    // IDTProxyHeader is the header name to proxy ID token if exists.
182    // Token is not proxied when the value is empty.
183    // Default is [""].
184    string IDTProxyHeader = 10 [json_name = "idtProxyHeader"];
185
186    TokenValidation ATValidation  = 11 [json_name = "atValidation"];
187    TokenValidation IDTValidation = 12 [json_name = "idtValidation"];
188}
189
190message AuthorizationRequestObject {
191    // [OPTIONAL]
192    // RequestURIPath specifies the URI for the request object by reference
193    // used for OpenID Connect authorization requests.
194    // If this field is set, it allows OpenID Connect requests to be passed by reference.
195    // Note: To use RequestObjectURI, EnabledRequestObject must be set to true.
196    string RequestURI = 1 [json_name = "requestURI"];
197
198    // [OPTIONAL]
199    // JWTHandler is the configuration for JWT handlers.
200    // JWTHandler is a required parameter of AuthorizationRequestObject.
201    JWTHandlerSpec JWTHandler = 2 [json_name = "jwtHandler"];
202
203    // [OPTIONAL]
204    // Exp specifies the remaining time in seconds before the request object expires.
205    // Default is [0].
206    int64 Exp = 3 [json_name = "exp", (buf.validate.field).int64 = {gte : 0}];
207
208    // [OPTIONAL]
209    // NbfLeeway compensates for clock skew by adding a grace period in seconds to the nbf claim.
210    // Default is [0].
211    int64 Nbf = 4 [json_name = "nbf", (buf.validate.field).int64 = {gte : 0}];
212
213    // [OPTIONAL]
214    // Disablecache set to true adds a Base64URL-encoded SHA-256 hash to request_uri to disable caching.
215    // Default is [false].
216    bool DisableCache = 5 [json_name = "disableCache"];
217}
218
219message AuthorizationResponseJARM {
220    // [OPTIONAL]
221    // ResponseModeMethod is the method of response_mode parmeter
222    // used for authorization request.
223    // Default is [ResponseModeJWT].
224    ResponseModeMethod ResponseMode = 1 [json_name = "responseMode"];
225
226    // [OPTIONAL]
227    // JWTHandler is the configuration for JWT handlers.
228    JWTHandlerSpec JWTHandler = 2 [json_name = "jwtHandler"];
229}
230
231// ResponseModeMethod is the method of response_mode parmeter
232// used for authorization responses.
233// Method is defined in https://openid.net/specs/openid-financial-api-jarm.html
234enum ResponseModeMethod {
235    ResponseModeJWT         = 0;
236    ResponseModeQueryJWT    = 1;
237    ResponseModeFragmentJWT = 2;
238    ResponseModeFormPostJWT = 3;
239}
240
241message AuthorizationCodeHandler {
242    bool       DisableState        = 1 [json_name = "disableState"];
243    bool       DisableNonce        = 2 [json_name = "disableNonce"];
244    bool       DisablePKCE         = 3 [json_name = "disablePKCE"];
245    PKCEMethod PKCEMethod          = 4 [json_name = "pkceMethod"];
246    string     LoginPath           = 5 [json_name = "loginPath"];
247    string     CallbackURL         = 6 [json_name = "callbackURL"];
248    string     RedirectPath        = 7 [json_name = "redirectPath"];
249    string     RedirectKey         = 8 [json_name = "redirectKey"];
250    string     RedirectPathPattern = 9 [json_name = "redirectPathPattern"];
251
252    // [OPTIONAL]
253    // RedirectToLogin is the flag to redirect unauthenticated users
254    // to the login url.
255    // This value is prior to the UnauthorizeAny when set to true.
256    // Default ["false"].
257    bool RedirectToLogin = 10 [json_name = "redirectToLogin"];
258
259    // [OPTIONAL]
260    // UnauthorizeAny disallow to access any path except for login path
261    // when users are not authenticated.
262    // If this field is set to false, users are redirected to login path
263    // when they have not been authenticated yet.
264    // If true, unauthorized error will be returned.
265    // This value is prior to the RestoreRequest when set to true.
266    // Default is ["false"]
267    bool UnauthorizeAny = 11 [json_name = "unauthorizeAny"];
268
269    // [OPTIONAL]
270    // RestoreRequest allow users to access any path
271    // even they have not been authenticated yet.
272    // Initial API requests will temporarily  be stored in the session
273    // while users are taking authentication processes and
274    // be restored after they come back to callback path
275    // after authentication.
276    // Default is ["false"]
277    bool RestoreRequest = 12 [json_name = "restoreRequest"];
278
279    // [OPTIONAL]
280    // URLParams is the list of additional url parameters
281    // for authentication request.
282    // Default is not set.
283    repeated string URLParams = 13 [json_name = "urlParams"];
284
285    // [Optional]
286    // UserInfoPath is the URL path to access the UserInfo endpoint of the OpenID provider.
287    // If not set, AILERON's downstream applications cannot access the UserInfo endpoint.
288    string UserInfoPath = 14 [json_name = "userInfoPath"];
289
290    // [OPTIONAL]
291    // EnabledFAPI ensures client security by following the
292    // Financial-grade API specifications.
293    // Default is [false].
294    bool EnabledFAPI = 15 [json_name = "enabledFAPI"];
295
296    // [OPTIONAL]
297    // RequestObject specifies whether the request object method
298    // is used for OpenID Connect authorization requests.
299    AuthorizationRequestObject RequestObject = 16 [json_name = "requestObject"];
300
301    // [OPTIONAL]
302    // JARM specifies whether the response mode method
303    // is used for authorization responses.
304    AuthorizationResponseJARM JARM = 17 [json_name = "jarm"];
305}
306
307// ClientCredentialsHandler is the specification of ClientCredentialsHandler object.
308message ClientCredentialsHandler {
309}
310
311// ResourceServerHandler is the specification of ResourceServerHandler object.
312message ResourceServerHandler {
313    // [OPTIONAL]
314    // Header key name to get access token from.
315    // Default is ["Authorization"]
316    string HeaderKey = 1 [json_name = "headerKey"];
317
318    // [OPTIONAL]
319    // EnabledFAPI enables token validation by following the
320    // Financial-grade API specifications.
321    // Default is [false].
322    bool EnabledFAPI = 2 [json_name = "enabledFAPI"];
323}
324
325message ROPCHandler {
326    // [OPTIONAL]
327    // RedeemTokenPath is the url path to redeem access token
328    // by exchangind with the username and password.
329    // If not set, username and password have to be sent
330    // for every requests.
331    string RedeemTokenPath = 1 [json_name = "redeemTokenPath"];
332
333    // [OPTIONAL]
334    // UsernameKey is the key to obtain username from
335    // Post form request body.
336    // Both UsernameKey and PasswordKey have to be set
337    // when sending the username and password with
338    // Post form request. Otherwise, they should be
339    // sent with authorization basic header.
340    string UsernameKey = 2 [json_name = "usernameKey"];
341
342    // [OPTIONAL]
343    // PasswordKey is the key to obtain password from
344    // Post form request body.
345    // Both UsernameKey and PasswordKey have to be set
346    // when sending the username and password with
347    // Post form request. Otherwise, they should be
348    // sent with authorization basic header.
349    string PasswordKey = 3 [json_name = "passwordKey"];
350}
351
352message TokenValidation {
353    // [OPTIONAL]
354    // SkipUnexpired is the flag to skip token validation
355    // if the token is not expired.
356    // This flag works only when the exp claim is
357    // available in the tokens and the tokens are
358    // restored from session objects.
359    // That means the authentication flow that do not use
360    // session cannot use this flag.
361    // Default is [false].
362    bool SkipUnexpired = 1 [json_name = "skipUnexpired"];
363
364    // [OPTIONAL]
365    // Iss is the valid value of iss claim
366    // that is used for token validations.
367    // Set "-" to disable iss claim validation.
368    // Default is the provider's issuer.
369    string Iss = 2 [json_name = "iss"];
370
371    // [OPTIONAL]
372    // Aud is the valid value of aud claim
373    // that is used for token validations.
374    // Set "-" to disable aud claim validation.
375    // Default is the client id.
376    string Aud = 3 [json_name = "aud"];
377
378    // [OPTIONAL]
379    // ExpOptional is the flag to make the exp claim optional.
380    // If true, validation of the exp claim is done only when
381    // the exp was present in the claims.
382    // If false, exp claim is mandate and always be validated.
383    // This field is bounded to the
384    // https://pkg.go.dev/github.com/golang-jwt/jwt/v5#WithExpirationRequired
385    // Default is [false].
386    bool ExpOptional = 4 [json_name = "expOptional"];
387
388    // [OPTIONAL]
389    // IatDisabled is the flag to disable validation of iat claim.
390    // If true, validation of the iat claim is skipped even
391    // the iat was found in the claims.
392    // If false, iat claim is validated only when the iat
393    // is present in the claims.
394    // This field is bounded to the
395    // https://pkg.go.dev/github.com/golang-jwt/jwt/v5#WithIssuedAt
396    // Default is [false].
397    bool IatDisabled = 5 [json_name = "iatDisabled"];
398
399    // [OPTIONAL]
400    // Leeway is the time duration in second.
401    // exp claim will be (exp + leeway), nbf claim will be (nbf - leeway),
402    // iat claim will be (iat - leeway < now).
403    // This field is bounded to the
404    // https://pkg.go.dev/github.com/golang-jwt/jwt/v5#WithLeeway
405    // Default is [5] second.
406    int32 Leeway = 6 [json_name = "leeway"];
407
408    // [OPTIONAL]
409    // ValidMethods is the allowed algorithms list of JWT singning methods.
410    // Only JWTs signed with the algorithms listed here are valid.
411    // If not set, all algorithms are allowed.
412    // This field is bounded to the
413    // https://pkg.go.dev/github.com/golang-jwt/jwt/v5#WithValidMethods
414    // Default is not set.
415    repeated string ValidMethods = 7 [json_name = "validMethods"];
416}

最終更新 June 7, 2025: add japanese (f2a41f1)