# 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.
Login required?} -->|No| C{Request database.
Consent required?} C -->|Yes| CL[Consent & login form] CL --> D C -->|No| W[Redirect to website
with token] A -->|Yes| CL CL --> M[/Magic-link/] M --> U{Request database.
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
#fragment or
?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.