355 lines
13 KiB
YAML
355 lines
13 KiB
YAML
openapi: 3.1.0
|
|
info:
|
|
title: Lacpass Authentication Server
|
|
description: Authentication endpoints
|
|
version: 1.0.0
|
|
|
|
servers:
|
|
- url: 'http://localhost:8082'
|
|
components:
|
|
securitySchemes:
|
|
bearerAuth:
|
|
type: http
|
|
scheme: bearer
|
|
bearerFormat: JWT
|
|
description: "Access token obtained via the Token endpoint."
|
|
schemas:
|
|
Account:
|
|
type: object
|
|
properties:
|
|
username:
|
|
type: string
|
|
firstName:
|
|
type: string
|
|
lastName:
|
|
type: string
|
|
email:
|
|
type: string
|
|
emailVerified:
|
|
type: boolean
|
|
attributes:
|
|
type: object
|
|
additionalProperties:
|
|
type: array
|
|
items:
|
|
type: string
|
|
UserRepresentation:
|
|
type: object
|
|
description: "Represents the current user's profile."
|
|
properties:
|
|
id:
|
|
type: string
|
|
readOnly: true
|
|
description: "User's ID."
|
|
username:
|
|
type: string
|
|
description: "User's username."
|
|
firstName:
|
|
type: string
|
|
description: "User's first name."
|
|
lastName:
|
|
type: string
|
|
description: "User's last name."
|
|
email:
|
|
type: string
|
|
format: email
|
|
description: "User's email address."
|
|
emailVerified:
|
|
type: boolean
|
|
readOnly: true
|
|
description: "Indicates if the user's email has been verified."
|
|
attributes:
|
|
type: object
|
|
additionalProperties:
|
|
type: string
|
|
description: "A map of custom user attributes."
|
|
SessionRepresentation:
|
|
type: object
|
|
description: "Represents an active user session."
|
|
properties:
|
|
id:
|
|
type: string
|
|
description: "Session ID."
|
|
ipAddress:
|
|
type: string
|
|
description: "IP address from which the session was initiated."
|
|
started:
|
|
type: integer
|
|
format: int64
|
|
description: "Timestamp of when the session started."
|
|
lastAccess:
|
|
type: integer
|
|
format: int64
|
|
description: "Timestamp of the last access in this session."
|
|
current:
|
|
type: boolean
|
|
description: "Indicates if this is the current session"
|
|
browser:
|
|
type: string
|
|
description: "Browser or user agent."
|
|
os:
|
|
type: string
|
|
description: "Operating system."
|
|
Error:
|
|
type: object
|
|
description: "Error"
|
|
properties:
|
|
error:
|
|
type: string
|
|
description: "Error type"
|
|
examples: ["invalid_request"]
|
|
error_description:
|
|
type: string
|
|
description: "Error description"
|
|
examples: ["Missing form parameter: grant_type"]
|
|
examples:
|
|
InvalidRequestError:
|
|
value:
|
|
error: "invalid_request"
|
|
error_description: "Missing form parameter: grant_type"
|
|
summary: "Invalid request"
|
|
InvalidUserCredentialsError:
|
|
value:
|
|
error: "invalid_grant"
|
|
error_description: "Invalid user credentials"
|
|
summary: "Invalid user credentials"
|
|
MaximumRefreshTokenUsesExceeded:
|
|
value:
|
|
error: "invalid_grant"
|
|
error_description: "Maximum allowed refresh token reuse exceeded"
|
|
summary: "Maximum allowed refresh token reuse exceeded"
|
|
|
|
|
|
# Group the endpoints into logical tabs.
|
|
tags:
|
|
- name: Authentication
|
|
description: "Endpoints for user authentication (OpenID Connect)."
|
|
- name: User
|
|
description: "Endpoints for user account"
|
|
|
|
paths:
|
|
/realms/{realm}/protocol/openid-connect/token:
|
|
post:
|
|
tags:
|
|
- Authentication
|
|
summary: "Get Token"
|
|
description: "Exchanges user credentials for an access and refresh tokens"
|
|
parameters:
|
|
- name: realm
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
examples: ["lacpass"]
|
|
description: "Name of the realm."
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/x-www-form-urlencoded:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
grant_type:
|
|
description: "Can be either `password` or `refresh_token`."
|
|
type: string
|
|
enum:
|
|
- password
|
|
- refresh_token
|
|
examples: ["password", "refresh_token"]
|
|
client_id:
|
|
description: "The ID of the client application."
|
|
type: string
|
|
enum:
|
|
- app
|
|
examples: ["app"]
|
|
refresh_token:
|
|
description: "Refresh token when `grant_type` refresh_token is used."
|
|
type: string
|
|
example: "eyJhbGciOiJIUzUxMiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICI1ZjA5MWRkYy1kNDQ3LTQ0OGYtODBmOS01NDUyYmRiMjM0ZjQifQ.eyJleHAiOjE3NTAxNzc3OTYsImlhdCI6MTc1MDA5MTM5NiwianRpIjoiNWJiMDNkMWQtYmY2Yy00MDZjLWI5NTktYmMzMjY4NjY3MjJlIiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgyL3JlYWxtcy9sYWNwYXNzIiwiYXVkIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgyL3JlYWxtcy9sYWNwYXNzIiwic3ViIjoiNjYwMWIzMjYtOTU5Yi00ZWNkLTliOGMtYTkzNThkNjAxYzRhIiwidHlwIjoiUmVmcmVzaCIsImF6cCI6ImFwcCIsInNpZCI6IjRiODM5OWU3LTNjYzUtNDJjZi1hNTJhLWY3MmZkOTE1MGM0MyIsInNjb3BlIjoid2ViLW9yaWdpbnMgYmFzaWMgcHJvZmlsZSByb2xlcyBlbWFpbCBhY3IiLCJyZXVzZV9pZCI6IjZmNDRkMTkzLWQwODQtNGU5Yi1iMWY1LWNkNTI1OWQyZWY5NiJ9.8yv3KVAyiBNQ2q9rcO0_oHdEBfQ5eJfRLVoCsYRCQsLMwfdV9Jc4NOmIXc337artKwY8c6k0_1ILhud-STPuJg"
|
|
required: false
|
|
username:
|
|
type: string
|
|
description: "User's email. Required when `grant_type` is password."
|
|
examples: ["jdoe@example.com"]
|
|
required: false
|
|
password:
|
|
type: string
|
|
description: "User's password. Required when `grant_type` is password."
|
|
examples: ["secret-password"]
|
|
required: false
|
|
scope:
|
|
type: string
|
|
description: "The scopes being requested. `openid` scope should always be present"
|
|
examples: ["openid profile email"]
|
|
required: false
|
|
responses:
|
|
'200':
|
|
description: "Authentication successful."
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
access_token:
|
|
type: string
|
|
example: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMn0.KMUFsIDTnFmyG3nMiGM6H9FNFUROf3wh7SmqJp-QV30"
|
|
refresh_token:
|
|
type: string
|
|
example: "pvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMn0.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMn0.KMUFsIDTnFmyG3nMiGM6H9FNFUROf3wh7SmqJp-QV30"
|
|
not-before-policy:
|
|
type: integer
|
|
example: 0
|
|
session_state:
|
|
type: string
|
|
example: "9c238c37-1021-43b3-a122-67301500a61d"
|
|
scope:
|
|
type: string
|
|
example: "profile email"
|
|
expires_in:
|
|
type: integer
|
|
example: 123058381
|
|
refresh_expires_in:
|
|
type: integer
|
|
example: 181283903
|
|
token_type:
|
|
type: string
|
|
example: "Bearer"
|
|
'401':
|
|
description: "Bad Request - a required parameter is missing or invalid."
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/Error'
|
|
examples:
|
|
invalidRequest:
|
|
$ref: '#/components/examples/InvalidRequestError'
|
|
invalidUserCredentials:
|
|
$ref: '#/components/examples/InvalidUserCredentialsError'
|
|
MaximumRefreshTokenUsesExceeded:
|
|
$ref: '#/components/examples/MaximumRefreshTokenUsesExceeded'
|
|
/realms/{realm}/protocol/openid-connect/logout:
|
|
post:
|
|
tags:
|
|
- Authentication
|
|
summary: "Log Out"
|
|
description: "Logs the user out of their session. Requires the refresh token to fully invalidate the session."
|
|
parameters:
|
|
- name: realm
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
description: "The name of the realm."
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/x-www-form-urlencoded:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
client_id:
|
|
type: string
|
|
description: "The ID of the client application."
|
|
examples: ["my-app-client"]
|
|
refresh_token:
|
|
type: string
|
|
description: "The refresh token obtained during login."
|
|
responses:
|
|
'204':
|
|
description: "Logout successful."
|
|
/realms/{realm}/protocol/openid-connect/userinfo:
|
|
get:
|
|
summary: "Get User Information"
|
|
description: "This endpoint returns claims about the authenticated end-user."
|
|
tags:
|
|
- User
|
|
parameters:
|
|
- name: realm
|
|
in: path
|
|
required: true
|
|
description: "The name of the realm."
|
|
schema:
|
|
type: string
|
|
security:
|
|
- bearerAuth: [ ]
|
|
responses:
|
|
"200":
|
|
description: "Successful response with user resource."
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
sub:
|
|
type: string
|
|
description: "User's id on the realm."
|
|
name:
|
|
type: string
|
|
description: "Full name."
|
|
given_name:
|
|
type: string
|
|
description: "Given name or first name."
|
|
family_name:
|
|
type: string
|
|
description: "Surname or last name."
|
|
preferred_username:
|
|
type: string
|
|
description: "Preferred username."
|
|
email:
|
|
type: string
|
|
format: email
|
|
description: "E-mail address."
|
|
email_verified:
|
|
type: boolean
|
|
description: "Indicates if the user's email has been verified."
|
|
locale:
|
|
type: string
|
|
description: "Preferred language."
|
|
document_type:
|
|
type: string
|
|
description: "Identity document type"
|
|
enum:
|
|
- passport
|
|
- id
|
|
identifier:
|
|
type: string
|
|
description: "Document identifier"
|
|
example:
|
|
sub: "a8c6d49a-72c7-4402-a1b1-7a5e9f8b4d6c"
|
|
name: "John Doe"
|
|
given_name: "John"
|
|
family_name: "Doe"
|
|
preferred_username: "jdoe"
|
|
email: "johndoe@example.com"
|
|
email_verified: true
|
|
locale: "en"
|
|
document_type: "passport"
|
|
identifier: "F12345678"
|
|
|
|
"401":
|
|
description: "Unauthorized. The request is missing a valid bearer token."
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
error:
|
|
type: string
|
|
example: "unauthorized"
|
|
error_description:
|
|
type: string
|
|
example: "Bearer token not provided or is invalid."
|
|
"403":
|
|
description: "Forbidden. The provided token does not have the required permissions (e.g., missing 'openid' scope)."
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
error:
|
|
type: string
|
|
example: "insufficient_scope"
|
|
error_description:
|
|
type: string
|
|
example: "The 'openid' scope is required."
|