168 lines
7.6 KiB
Markdown
168 lines
7.6 KiB
Markdown
# OpenID Connect
|
|
|
|
## Table of contents
|
|
|
|
* [Introduction](#introduction)
|
|
* [Authorization flow](#authorization-flow)
|
|
* [Visiting target website](#visiting-target-website)
|
|
* [Authentication & Authorization](#authentication-authorization)
|
|
* [JWT generation, delivery & validation](#jwt-generation-delivery-validation)
|
|
|
|
## Introduction
|
|
|
|
At the moment, the use of global websites is a serious problem for international companies when doing business in the Russian Federation.
|
|
According to Russian legislation on personal data foreign websites cannot process personal data of Russian citizens without first collecting and processing it in Russian databases.
|
|
|
|
The solution to this problem is to use a server located on the territory of the Russian Federation, which will collect the necessary data, update, store, and also allow end users to change the entered data, revoke consent, etc.
|
|
|
|
The proposed bellow system is such a solution that solves the problem of localizing personal data.
|
|
|
|
The system provides OpenID Connect provider services in accordance with [OpenID Connect Core 1.0](https://openid.net/specs/openid-connect-core-1_0.html) standard.
|
|
Follow the link to the specification to explore the core functionality of OpenID Connect: authentication built on top of [OAuth 2.0](https://oauth.net/2/), and the use of Claims to communicate information about the User.
|
|
|
|
Also, within the framework of the system, a [Staging](https://staging.ps.radium-it.ru/.well-known/openid-configuration) environment configuration is deployed, within which it is possible to test the services of the OpenID Connect Authorization Server.
|
|
|
|
It is important to note that the address of the Production server will be different from the Staging environment.
|
|
By default, production server is located under https://client.ps.radium-it.ru.
|
|
To customize a web address of the oidc Authorization Server, for example, https://privacy.client.ru or you need to add a CNAME Record to your DNS server.
|
|
|
|
In addition, the system assumes a jwks_endpoint, provided by the oidc Authorization Server, from which public keys can be obtained to verify the signature of signed JWT (https://staging.ps.radium-it.ru/.well-known/jwks.json).
|
|
All the necessary information regarding the configuration is available [here](https://openid.net/specs/openid-connect-core-1_0.html#RFC6749).
|
|
|
|
Futher, a more detailed mechanism of the system operation on the OpenID Connect protocol, examples of requests, data flows, etc will be presented.
|
|
We provide an opportunity to study our system and try out the work in the configuration of the described algorithm.
|
|
|
|
## Authorization flow
|
|
|
|
```mermaid
|
|
sequenceDiagram
|
|
autonumber
|
|
Visitor->>Website: Sign me in
|
|
Website->>Visitor: Obtain token from OIDC
|
|
Visitor->>OIDC: Authorize website
|
|
OIDC->>Visitor: Token for Website
|
|
Visitor->>Website: Sign me in with token
|
|
Website-->>OIDC: Userinfo?
|
|
OIDC-->>Website: {"email": "user@site.tld"}
|
|
Website-)Visitor: Signed in
|
|
```
|
|
|
|
### Visiting target website
|
|
|
|
```mermaid
|
|
flowchart LR
|
|
U[User]-->W(Website)
|
|
W--> A{Authenticated?}
|
|
A-->|Yes| AC[Grant access]
|
|
A-->|No| R[/redirect/]
|
|
R-->O[OpenID Connect Provider]
|
|
```
|
|
|
|
When an User visits a Website, the Website determines whether the User is known for the Website or is visiting the site for the first time.
|
|
This check can be done by analyzing a request from the user for the presence of cookies.
|
|
|
|
If no data about the User is found, the Website needs to identify the User.
|
|
To do this, the Website redirects the User to the OpenID Provider and includes in the request `client_id`, `redirect_uri`, `response_type` and one or more `scope` (permissions), that it needs.
|
|
|
|
**NOTE:**
|
|
|
|
`redirect_uri` is the address of the Website's page that can process the response from the provider.
|
|
`redirect_uri` and `client_id` shall be pre-registered at the provider.
|
|
|
|
Example of redirect response:
|
|
|
|
```
|
|
HTTP/1.1 302 Found
|
|
Location: https://{OIDC_SERVER}/oidc/authorize?scope=openid&redirect_uri={REDIRECT_URI}&client_id={CLIENT_ID}&response_type=id_token"
|
|
```
|
|
|
|
### Authentication & authorization
|
|
|
|
NOTE: The system currently supports only [Implicit Flow](https://openid.net/specs/openid-connect-core-1_0.html#ImplicitFlowAuth)
|
|
|
|
```mermaid
|
|
flowchart TB
|
|
A{Process cookies.<br>Login required?} -->|No| C{Request database.<br>Consent required?}
|
|
C -->|Yes| CL[Consent & login form]
|
|
CL --> D
|
|
C -->|No| W[Redirect to website<br>with token]
|
|
A -->|Yes| CL
|
|
CL --> M[/Magic-link/]
|
|
M --> U{Request database.<br>Registered?}
|
|
U -->|Yes| CC[/Write auth cookie/] --> D
|
|
U -->|No| RF[Registration form] --> CC
|
|
D[(Store)] -->|redirect| W
|
|
```
|
|
|
|
If the user has already been in contact with the oidc Authorization Server, browser sends the existing cookies to the oidc Authorization Server along with the request.
|
|
|
|
The following is a non-normative example request using the Implicit Flow that would be sent by the Browser to the OIDC Authorization Server:
|
|
|
|
```
|
|
GET /oidc/authorize?
|
|
response_type=id_token
|
|
&client_id=s6BhdRkqt3
|
|
&redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb
|
|
&scope=openid%20profile
|
|
&state=af0ifjsldkj
|
|
&nonce=n-0S6_WzA2Mj HTTP/1.1
|
|
Host: staging.ps.radium-it.ru
|
|
```
|
|
|
|
If the User has already been authenticated, Authorization Endpoint asks the database if the User's consent has been obtained for that Website.
|
|
|
|
If consent for the client (Website) has already been given by the User, the OIDC Authorization Server redirects the User to the address that was specified in the `redirect_uri` with some extra data according to the specification.
|
|
|
|
If User is not authenticated or consent for the client has not yet been given by User, the OIDC Authorization Server displays a Consent form with a list of all Scopes requested by the Website, as well as a checkbox to confirm consent to the processing of personal data.
|
|
|
|
**NOTE:**
|
|
|
|
The Authorization Server will attempt to authenticate the User in the following cases:
|
|
|
|
- The User is not already authenticated.
|
|
- The authentication request contains the `prompt` parameter with the value `login`.
|
|
|
|
More information can be found [here](https://openid.net/specs/openid-connect-core-1_0.html#Authenticates)
|
|
|
|
### JWT generation, delivery & validation
|
|
|
|
```mermaid
|
|
flowchart TB
|
|
OP[OIDC]-->R[/Make redirect URI/]
|
|
JWKS[JWKS]
|
|
subgraph Token generation
|
|
U[(Database)] -->|Claims| TS
|
|
TS[/sign/] --> T[Token]
|
|
end
|
|
subgraph Token usage
|
|
W[Website] --> TT[/Take token from<br>#fragment or <br>?query/]
|
|
TT --> TP[Verify token]
|
|
TP -->|user authenticated| TU(Use token)
|
|
end
|
|
T -.-> R
|
|
JWKS -.->|private key| TS
|
|
JWKS -.->|public key| TP
|
|
R -->|redirect user| W
|
|
```
|
|
|
|
As a result of the authentication User is redirected to `redirect_uri` with data included in query or fragment of the address (see the specification).
|
|
After all the necessary data about the User has been collected, the OIDC Authorization Server sends the following response to the User, containing a link to the website and the `id_token` (JWT - JSON Web Token):
|
|
|
|
```
|
|
HTTP/1.1 302 Found
|
|
Location: https://client.example.org/cb#
|
|
id_token=eyJ0 ... NiJ9.eyJ1c ... I6IjIifX0.DeWt4Qu ... ZXso
|
|
&expires_in=3600
|
|
&state=af0ifjsldkj
|
|
```
|
|
|
|
The `id_token` (JWT) is a base64 encoded urlsafe string.
|
|
More information on `id_token` data structure can be found [here](https://openid.net/specs/openid-connect-core-1_0.html#IDToken).
|
|
|
|
JWT contains signature signed with the private key of the OIDC Provider.
|
|
The client shall verify that JWT is signed by corresponding to `kid` public key contained in JWKS `jwks_endpoint`.
|
|
|
|
See [specification](https://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation) for more details.
|
|
|
|
The website can now use the JWT to get the necessary information about the User.
|