-
Notifications
You must be signed in to change notification settings - Fork 533
/
Program.cs
197 lines (157 loc) · 9.83 KB
/
Program.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.IdentityModel.JsonWebTokens;
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
using BlazorWebAppOidc;
using BlazorWebAppOidc.Client.Weather;
using BlazorWebAppOidc.Components;
using BlazorWebAppOidc.Weather;
const string MS_OIDC_SCHEME = "MicrosoftOidc";
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddAuthentication(MS_OIDC_SCHEME)
.AddOpenIdConnect(MS_OIDC_SCHEME, oidcOptions =>
{
// For the following OIDC settings, any line that's commented out
// represents a DEFAULT setting. If you adopt the default, you can
// remove the line if you wish.
// ........................................................................
// The OIDC handler must use a sign-in scheme capable of persisting
// user credentials across requests.
oidcOptions.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
// ........................................................................
// ........................................................................
// The "openid" and "profile" scopes are required for the OIDC handler
// and included by default. You should enable these scopes here if scopes
// are provided by "Authentication:Schemes:MicrosoftOidc:Scope"
// configuration because configuration may overwrite the scopes collection.
//oidcOptions.Scope.Add(OpenIdConnectScope.OpenIdProfile);
// ........................................................................
// ........................................................................
// The following paths must match the redirect and post logout redirect
// paths configured when registering the application with the OIDC provider.
// For Microsoft Entra ID, this is accomplished through the "Authentication"
// blade of the application's registration in the Azure portal. Both the
// signin and signout paths must be registered as Redirect URIs. The default
// values are "/signin-oidc" and "/signout-callback-oidc".
// Microsoft Identity currently only redirects back to the
// SignedOutCallbackPath if authority is
// https://login.microsoftonline.com/{TENANT ID}/v2.0/ as it is above.
// You can use the "common" authority instead, and logout redirects back to
// the Blazor app. For more information, see
// https://github.com/AzureAD/microsoft-authentication-library-for-js/issues/5783
//oidcOptions.CallbackPath = new PathString("/signin-oidc");
//oidcOptions.SignedOutCallbackPath = new PathString("/signout-callback-oidc");
// ........................................................................
// ........................................................................
// The RemoteSignOutPath is the "Front-channel logout URL" for remote single
// sign-out. The default value is "/signout-oidc".
//oidcOptions.RemoteSignOutPath = new PathString("/signout-oidc");
// ........................................................................
// ........................................................................
// The following example Authority is configured for Microsoft Entra ID
// and a single-tenant application registration. Set the {TENANT ID}
// placeholder to the Tenant ID. The "common" Authority
// https://login.microsoftonline.com/common/v2.0/ should be used
// for multi-tenant apps. You can also use the "common" Authority for
// single-tenant apps, but it requires a custom IssuerValidator as shown
// in the comments below.
oidcOptions.Authority = "https://login.microsoftonline.com/{TENANT ID}/v2.0/";
// ........................................................................
// ........................................................................
// Set the Client ID for the app. Set the {CLIENT ID} placeholder to
// the Client ID.
oidcOptions.ClientId = "{CLIENT ID}";
// ........................................................................
// ........................................................................
// ClientSecret shouldn't be compiled into the application assembly or
// checked into source control. Adopt User Secrets, Azure KeyVault,
// or an environment variable to supply the value. Authentication scheme
// configuration is automatically read from
// "Authentication:Schemes:{SchemeName}:{PropertyName}", so ClientSecret is
// for OIDC configuration is automatically read from
// "Authentication:Schemes:MicrosoftOidc:ClientSecret" configuration.
//oidcOptions.ClientSecret = "{PREFER NOT SETTING THIS HERE}";
// ........................................................................
// ........................................................................
// Setting ResponseType to "code" configures the OIDC handler to use
// authorization code flow. Implicit grants and hybrid flows are unnecessary
// in this mode. In a Microsoft Entra ID app registration, you don't need to
// select either box for the authorization endpoint to return access tokens
// or ID tokens. The OIDC handler automatically requests the appropriate
// tokens using the code returned from the authorization endpoint.
oidcOptions.ResponseType = OpenIdConnectResponseType.Code;
// ........................................................................
// ........................................................................
// Many OIDC servers use "name" and "role" rather than the SOAP/WS-Fed
// defaults in ClaimTypes. If you don't use ClaimTypes, mapping inbound
// claims to ASP.NET Core's ClaimTypes isn't necessary.
oidcOptions.MapInboundClaims = false;
oidcOptions.TokenValidationParameters.NameClaimType = JwtRegisteredClaimNames.Name;
oidcOptions.TokenValidationParameters.RoleClaimType = "role";
// ........................................................................
// ........................................................................
// Many OIDC providers work with the default issuer validator, but the
// configuration must account for the issuer parameterized with "{TENANT ID}"
// returned by the "common" endpoint's /.well-known/openid-configuration
// For more information, see
// https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/issues/1731
//var microsoftIssuerValidator = AadIssuerValidator.GetAadIssuerValidator(oidcOptions.Authority);
//oidcOptions.TokenValidationParameters.IssuerValidator = microsoftIssuerValidator.Validate;
// ........................................................................
// ........................................................................
// OIDC connect options set later via ConfigureCookieOidcRefresh
//
// (1) The "offline_access" scope is required for the refresh token.
//
// (2) SaveTokens is set to true, which saves the access and refresh tokens
// in the cookie, so the app can authenticate requests for weather data and
// use the refresh token to obtain a new access token on access token
// expiration.
// ........................................................................
})
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme);
// ConfigureCookieOidcRefresh attaches a cookie OnValidatePrincipal callback to get
// a new access token when the current one expires, and reissue a cookie with the
// new access token saved inside. If the refresh fails, the user will be signed
// out. OIDC connect options are set for saving tokens and the offline access
// scope.
builder.Services.ConfigureCookieOidcRefresh(CookieAuthenticationDefaults.AuthenticationScheme, MS_OIDC_SCHEME);
builder.Services.AddAuthorization();
builder.Services.AddCascadingAuthenticationState();
builder.Services.AddRazorComponents()
.AddInteractiveServerComponents()
.AddInteractiveWebAssemblyComponents();
builder.Services.AddScoped<AuthenticationStateProvider, PersistingAuthenticationStateProvider>();
builder.Services.AddScoped<IWeatherForecaster, ServerWeatherForecaster>();
builder.Services.AddHttpContextAccessor();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseWebAssemblyDebugging();
}
else
{
app.UseExceptionHandler("/Error", createScopeForErrors: true);
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAntiforgery();
var summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};
app.MapGet("/weather-forecast", ([FromServices] IWeatherForecaster WeatherForecaster) =>
{
return WeatherForecaster.GetWeatherForecastAsync();
}).RequireAuthorization();
app.MapRazorComponents<App>()
.AddInteractiveServerRenderMode()
.AddInteractiveWebAssemblyRenderMode()
.AddAdditionalAssemblies(typeof(BlazorWebAppOidc.Client._Imports).Assembly);
app.MapGroup("/authentication").MapLoginAndLogout();
app.Run();