OpenID Connect
OAuth 2.0 vs OpenID Connect
OAuth 2.0 is designed strictly for authorization. It allows one application to grant another application access to its data or functionality. The client receives an access token which it uses to access data on the resource server, but it does not learn anything about the user. OAuth has been (mis)used for authentication, but since it was not designed for this purpose, OpenID Connect was introduced as an extension to support authentication.
OpenID Connect is a thin layer on top of OAuth 2.0 that adds identity authentication. You may have seen login options like "Login with Google" or "Login with Facebook" — in these cases, OpenID Connect is often being used.
It allows a wide range of clients — including web, mobile, and JavaScript applications — to request and receive information about authenticated sessions and end-users.
Identity Providers
To solve the challenge of local authentication, Identity Providers (IdPs) were introduced. These providers manage user authentication, allowing your application to focus on core business logic. They verify and provide the user’s identity so that organizations can onboard users without directly collecting personal data.
It’s a win-win for both users and organizations: users avoid creating new accounts for every application, and organizations avoid storing personal data.
What is OpenID Connect?
Client applications need a standardized way to interact with Identity Providers. OpenID Connect is such a specification, defining how clients and IdPs should communicate.
OpenID Connect is the third version in the OpenID family, following OpenID 1.0 and 2.0. It is the most widely adopted version due to its simplicity and broad support.
It uses JWT (JSON Web Tokens) to transmit identity information, making it easy to integrate with various technologies.
Participants in OpenID Connect
- End User: The entity whose identity is being requested. Equivalent to "Resource Owner" in OAuth.
- Relying Party: The client application that relies on the identity provider.
- Identity Provider (IdP): The server that provides identity information, also known as the "Authorization Server" in OAuth.
Identity Token
OAuth uses the authorization code and access token. OpenID Connect introduces a third type: the identity token.
- It is a JWT containing identity information about the user.
- Read by the client, not the server.
- Must be validated before use.
Fields:
iss: Issuer (authorization server identity)aud: Audience (intended recipient — the client)exp: Expiration time
Example:
{
"iss": "https://server.example.com",
"sub": "24400320",
"aud": "s6BhdRkqt3",
"nonce": "n-0S6_WzA2Mj",
"exp": 1311281970,
"iat": 1311280970,
"auth_time": 1311280969,
"acr": "urn:mace:incommon:iap:silver"
}
iat: Issued Atauth_time: Time of user authenticationnonce: Prevents replay attacks
Note: The identity token contains only basic information. To get the full user profile, the client must use the access token at the UserInfo endpoint.
Scope
The scope defines what kind of user data the client requests from the IdP.
| Scope | Information |
|---|---|
email | Email address |
phone | Phone number |
profile | General user info |
address | User address |
openid | Required for identity token |
Claims
Claims are key-value pairs with user information.
- Example:
family_name: Papadopoulos - Requested via
scopeor specificclaimsparameter
| Scope | Included Claims |
|---|---|
email | email, email_verified |
phone | phone_number, phone_number_verified |
profile | name, family_name, given_name, etc. |
address | address |
Endpoints
Clients interact with these endpoints on the IdP:
- Authorization Endpoint: Authenticates the user, returns an authorization code
- Token Endpoint: Exchanges code for access and identity tokens
- UserInfo Endpoint: Returns additional user details via the access token
Example UserInfo Response:
{
"sub": "Joe",
"email": "Joe@dummy.net",
"email_verified": true,
"name": "Joe Frank"
}
Authorization Code Flow (Authentication)
This flow mirrors OAuth 2.0 but includes openid in the scope to trigger authentication.
Q&A
-
What happens if
openidis not in the scope?- The flow behaves like a standard OAuth flow.
- No identity token is issued, hence no user identity info.
-
Can the client access UserInfo endpoint without
openidscope?- No. The
openidscope is required along with others likeemail,profile.
- No. The
Example:
scope = "openid email"
- The client gets access to
emailinfo only. - No
addressorprofileinfo unless explicitly requested.
Summary:
scopemust includeopenidfor authentication.- Identity token and UserInfo response depend on requested scopes.
- Without
openid, the flow is authorization-only (OAuth).
Implementation in Django with social-auth-gsis
The OpenID Connect process and OAuth protocol are supported in our projects via the social-auth-gsis library.
PyPI: https://pypi.org/project/social-auth-gsis/#description
Configuration
1. Add social_django to INSTALLED_APPS:
INSTALLED_APPS = [
# ...
"social_django",
]
2. Add Middleware
MIDDLEWARE = [
...
"django.middleware.clickjacking.XFrameOptionsMiddleware",
"social_django.middleware.SocialAuthExceptionMiddleware",
]
3. Restrict user creation to Social Auth only
SOCIAL_AUTH_PIPELINE = (
"social_core.pipeline.social_auth.social_details",
"social_core.pipeline.social_auth.social_uid",
"social_core.pipeline.social_auth.auth_allowed",
"social_core.pipeline.social_auth.associate_user",
"social_core.pipeline.social_auth.load_extra_data",
"social_core.pipeline.user.user_details",
"social.social_auth.open_id_user",
)
open_id_useris a custom step for linking the logged-in user (via GSIS) to a user in the DB.
4. Environment Variables
SOCIAL_AUTH_OIDC_KEY=
SOCIAL_AUTH_OIDC_SECRET=
SOCIAL_AUTH_OIDC_ENDPOINT=https://auth.services.gov.gr/oidc
SOCIAL_AUTH_OIDC_REDIRECT_URL=https://<your-app>/oidc/authorize/
SOCIAL_AUTH_OIDC_CONFIGURATION_ENDPOINT=https://auth.services.gov.gr/.well-known/openid-configuration
5. Enable Backend
AUTHENTICATION_BACKENDS = (
"social.social_auth.OpenIdConnectPortalGSISOAuth2",
)
6. Backend Class
class OpenIdConnectPortalGSISOAuth2(OpenIdConnectAuth):
name = "oidc"
AUTHORIZATION_URL = f"{settings.SOCIAL_AUTH_OIDC_OIDC_ENDPOINT}/authorization/"
ACCESS_TOKEN_URL = f"{settings.SOCIAL_AUTH_OIDC_OIDC_ENDPOINT}/token/"
REDIRECT_URL = settings.SOCIAL_AUTH_OIDC_REDIRECT_URL
DEFAULT_SCOPE = ["openid", "profile"]
def get_redirect_uri(self, state=None):
return self.REDIRECT_URL
def oidc_config(self):
return self.get_json(settings.SOCIAL_AUTH_OIDC_CONFIGURATION_ENDPOINT)
URLs
Include the following in your Django URLs:
path("auth/", include("social_django.urls", namespace="social")),
path(
"oidc/authorize/",
social_django_views.complete,
kwargs={"backend": "oidc"},
name="oidc_authorize",
),
The URL /oidc/authorize/ maps to:
SOCIAL_AUTH_OIDC_REDIRECT_URL=https://<your-app>/oidc/authorize/
