Skip to content

Commit e8b5cb7

Browse files
Merge pull request #706 from DuendeSoftware/openid-connect-events
Add documentation for OIDC events in ASP.NET Core
2 parents 331c867 + 243cbf6 commit e8b5cb7

File tree

1 file changed

+185
-0
lines changed

1 file changed

+185
-0
lines changed
Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
---
2+
title: "ASP.NET Core OpenID Connect Handler Events"
3+
description: "ASP.NET Core's OpenID Connect handler events, what they are, and why you might want to use them."
4+
date: 2025-5-01
5+
sidebar:
6+
order: 60
7+
label: "OIDC Handler Events"
8+
---
9+
10+
The ASP.NET Core [OpenID Connect handler][handler] exposes events that a client can subscribe to intercept the OpenID
11+
Connect protocol flow. Understanding these events is important to understanding how to customize the OpenID Connect
12+
protocol flow from the client. We'll cover each of the events, what they are, and why you might want to subscribe to
13+
them.
14+
15+
To use the `OpenIdConnectHandler` in your client applications, you will first need to install the
16+
`Microsoft.AspNetCore.Authentication.OpenIdConnect` NuGet package.
17+
18+
```bash
19+
dotnet package add Microsoft.AspNetCore.Authentication.OpenIdConnect
20+
```
21+
22+
Followed by adding the `OpenIdConnectHandler` to your application.
23+
24+
```csharp
25+
// Program.cs
26+
builder.Services.AddAuthentication(options =>
27+
{
28+
options.DefaultScheme = "cookie";
29+
options.DefaultChallengeScheme = "oidc";
30+
options.DefaultSignOutScheme = "oidc";
31+
})
32+
.AddCookie("cookie", options =>
33+
{
34+
options.Cookie.Name = "__Host-bff";
35+
options.Cookie.SameSite = SameSiteMode.Strict;
36+
})
37+
.AddOpenIdConnect("oidc", options =>
38+
{
39+
options.Authority = "https://demo.duendesoftware.com";
40+
options.ClientId = "interactive.confidential";
41+
options.ClientSecret = "secret";
42+
options.ResponseType = "code";
43+
options.ResponseMode = "query";
44+
45+
options.GetClaimsFromUserInfoEndpoint = true;
46+
options.SaveTokens = true;
47+
options.MapInboundClaims = false;
48+
49+
options.Scope.Clear();
50+
options.Scope.Add("openid");
51+
options.Scope.Add("profile");
52+
options.Scope.Add("api");
53+
options.Scope.Add("offline_access");
54+
55+
options.TokenValidationParameters.NameClaimType = "name";
56+
options.TokenValidationParameters.RoleClaimType = "role";
57+
58+
});
59+
```
60+
61+
From here you can use the `options.Events` property to subscribe to the events you want to use. Let's look at each of the events in more detail.
62+
63+
## OpenID Connect Events
64+
65+
All events either occur before a request is sent to the identity provider, or after a response is received from the
66+
identity provider. Understanding the direction of these events can help you determine when to subscribe to them. Let's call events coming from the identity provider **incoming** and events going to the identity provider **outgoing** for an easier understanding.
67+
68+
| **Event Name** | **Usage** |
69+
|------------------------------------------|--------------|
70+
| `OnAuthenticationFailed` | **Incoming** |
71+
| `OnAuthorizationCodeReceived` | **Incoming** |
72+
| `OnMessageReceived` | **Incoming** |
73+
| `OnRedirectToIdentityProvider` | **Outgoing** |
74+
| `OnRedirectToIdentityProviderForSignOut` | **Outgoing** |
75+
| `OnSignedOutCallbackRedirect` | **Outgoing** |
76+
| `OnRemoteSignOut` | **Incoming** |
77+
| `OnTokenResponseReceived` | **Incoming** |
78+
| `OnTokenValidated` | **Incoming** |
79+
| `OnUserInformationReceived` | **Incoming** |
80+
| `OnPushAuthorization` (**.NET 9+ only**) | **Outgoing** |
81+
82+
## Commonly Subscribed Events
83+
84+
While there are many events available in the `OpenIdConnectEvents` class, only a few are commonly subscribed. We suggest you start with the most commonly subscribed events and then subscribe to the remaining events as needed.
85+
86+
For ASP.NET Core developers, the most commonly subscribed events are:
87+
88+
1. **`OnRedirectToIdentityProvider`**: Useful for customizing login requests (e.g., appending extra parameters).
89+
2. **`OnRedirectToIdentityProviderForSignOut`**: Often required to customize the behavior of sign-out requests.
90+
3. **`OnTokenValidated`**: Frequently used to customize the claims processing or validate custom claims included in the
91+
ID token.
92+
4. **`OnUserInformationReceived`**: Sometimes used to process additional user data retrieved from the UserInfo
93+
endpoint (if enabled).
94+
95+
## Descriptions
96+
97+
### OnAuthenticationFailed
98+
99+
- **When called**: Triggered whenever an exception occurs during the authentication process. This event provides an
100+
opportunity to handle or log errors.
101+
- **How often**: Only called when an authentication error happens.
102+
- **Example use case**: Use this event to log detailed error messages or display a custom error page to the user instead
103+
of the default behavior.
104+
- **Commonly subscribed**: No, unless you need specific error-handling logic.
105+
106+
### OnAuthorizationCodeReceived
107+
108+
- **When called**: Invoked after an authorization code is received and before it is redeemed for tokens.
109+
- **How often**: Called once per successful authorization code flow request.
110+
- **Example use case**: Validate the authorization code or add extra functionality (e.g., logging or monitoring) when
111+
the code is received.
112+
- **Commonly subscribed**: Rarely, unless custom logic is required before token redemption.
113+
114+
### OnMessageReceived
115+
116+
- **When called**: Triggered when a protocol message (e.g., an authorization response, logout request) is first
117+
received.
118+
- **How often**: Called once per incoming protocol message.
119+
- **Example use case**: Inspect or modify protocol messages for debugging or to handle additional query parameters
120+
passed by the identity provider.
121+
- **Commonly subscribed**: No, unless advanced customization is needed.
122+
123+
### OnRedirectToIdentityProvider
124+
125+
- **When called**: Invoked when redirecting the user to the identity provider for authentication. You can modify the
126+
outgoing authentication request.
127+
- **How often**: Called once per user authentication attempt (e.g., a "login").
128+
- **Example use case**: Add custom query parameters to the request or modify the state parameter.
129+
- **Commonly subscribed**: Yes—often used to customize the authentication request.
130+
131+
### OnRedirectToIdentityProviderForSignOut
132+
133+
- **When called**: Triggered before redirecting the user to the identity provider to start the sign-out process.
134+
- **How often**: Called once per user sign-out request.
135+
- **Example use case**: Modify the logout request, such as appending additional parameters.
136+
- **Commonly subscribed**: Yes, if signing out requires customization.
137+
138+
### OnSignedOutCallbackRedirect
139+
140+
- **When called**: Invoked after a remote sign-out is completed and before redirecting the user to the
141+
`SignedOutRedirectUri`.
142+
- **How often**: Called once per remote sign-out.
143+
- **Example use case**: Log or perform business logic after the remote sign-out.
144+
- **Commonly subscribed**: Rarely, unless additional behavior is needed.
145+
146+
### OnRemoteSignOut
147+
148+
- **When called**: Called when a remote sign-out request is received on the `RemoteSignOutPath` endpoint.
149+
- **How often**: Called once per incoming remote sign-out request.
150+
- **Example use case**: Perform cleanup tasks such as clearing local session data upon receiving a sign-out request from
151+
the identity provider.
152+
- **Commonly subscribed**: Rarely, but important in distributed or multi-tenant systems.
153+
154+
### OnTokenResponseReceived
155+
156+
- **When called**: Triggered after an authorization code exchange is completed and the token endpoint returns tokens.
157+
- **How often**: Called once per token request.
158+
- **Example use case**: Log or debug the token response, or inspect additional data included in the token response.
159+
- **Commonly subscribed**: No, unless debugging or inspection of tokens is required.
160+
161+
### OnTokenValidated
162+
163+
- **When called**: Invoked after the ID token has been validated and an `AuthenticationTicket` has been created.
164+
- **How often**: Called once per token validation process.
165+
- **Example use case**: Add or modify claims in the `ClaimsPrincipal` or validate custom claims included in the token.
166+
- **Commonly subscribed**: Yes—this is one of the most commonly used events for customizing claims.
167+
168+
### OnUserInformationReceived
169+
170+
- **When called**: Triggered when retrieving user information from the UserInfo endpoint (if
171+
`GetClaimsFromUserInfoEndpoint = true`).
172+
- **How often**: Called once per user information fetch (e.g., per login).
173+
- **Example use case**: Extend or modify user claims based on the additional information retrieved from the UserInfo
174+
endpoint.
175+
- **Commonly subscribed**: Sometimes, if extra claims processing is required.
176+
177+
### OnPushAuthorization
178+
179+
- **When called**: Invoked before sending authorization parameters using the Pushed Authorization Request (PAR)
180+
mechanism.
181+
- **How often**: Called once per outgoing PAR-based authorization request.
182+
- **Example use case**: Modify or log pushed authorization parameters.
183+
- **Commonly subscribed**: Rarely, as this is used mainly in advanced scenarios.
184+
185+
[handler]: https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.authentication.openidconnect.openidconnecthandler?view=aspnetcore-9.0

0 commit comments

Comments
 (0)