Skip to content
This repository was archived by the owner on Dec 21, 2024. It is now read-only.

Commit a9590ec

Browse files
committed
first round of updates for .NET 8 and IdentityServer 7.0
1 parent 1ea8f9b commit a9590ec

File tree

167 files changed

+2642
-1122
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

167 files changed

+2642
-1122
lines changed

global.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"sdk": {
3-
"version": "6.0.100",
3+
"version": "8.0.100",
44
"rollForward": "latestMajor",
55
"allowPrerelease": false
66
}

src/BffLocalApi/BffLocalApi.csproj

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
<Project Sdk="Microsoft.NET.Sdk.Web">
22

33
<PropertyGroup>
4-
<TargetFramework>net6.0</TargetFramework>
4+
<TargetFramework>net8.0</TargetFramework>
55
<ImplicitUsings>enable</ImplicitUsings>
66
</PropertyGroup>
77

88
<ItemGroup>
9-
<PackageReference Include="Duende.BFF.Yarp" Version="2.1.0" />
10-
<PackageReference Include="Serilog.AspNetCore" Version="6.0.0" />
9+
<PackageReference Include="Duende.BFF.Yarp" Version="2.2.0" />
10+
<PackageReference Include="Serilog.AspNetCore" Version="8.0.0" />
1111

12-
<PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="6.0.0" />
12+
<PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="8.0.0" />
1313
</ItemGroup>
1414

1515
</Project>

src/BffRemoteApi/BffRemoteApi.csproj

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
<Project Sdk="Microsoft.NET.Sdk.Web">
22

33
<PropertyGroup>
4-
<TargetFramework>net6.0</TargetFramework>
4+
<TargetFramework>net8.0</TargetFramework>
55
<Nullable>enable</Nullable>
66
<ImplicitUsings>enable</ImplicitUsings>
77
</PropertyGroup>
88

99
<ItemGroup>
10-
<PackageReference Include="Duende.BFF.Yarp" Version="2.1.0" />
10+
<PackageReference Include="Duende.BFF.Yarp" Version="2.2.0" />
1111
</ItemGroup>
1212

1313

Original file line numberDiff line numberDiff line change
@@ -1,20 +1,21 @@
11
<Project Sdk="Microsoft.NET.Sdk.Web">
22

33
<PropertyGroup>
4-
<TargetFramework>net6.0</TargetFramework>
4+
<TargetFramework>net8.0</TargetFramework>
55
<ImplicitUsings>enable</ImplicitUsings>
6+
<Nullable>enable</Nullable>
67
</PropertyGroup>
78

89
<ItemGroup>
9-
<PackageReference Include="Duende.IdentityServer.AspNetIdentity" Version="6.3.2" />
10+
<PackageReference Include="Duende.IdentityServer.AspNetIdentity" Version="7.0.0-rc.2" />
1011

11-
<PackageReference Include="Microsoft.AspNetCore.Authentication.Google" Version="6.0.0" />
12-
<PackageReference Include="Serilog.AspNetCore" Version="6.0.0" />
12+
<PackageReference Include="Microsoft.AspNetCore.Authentication.Google" Version="8.0.0" />
13+
<PackageReference Include="Serilog.AspNetCore" Version="8.0.0" />
1314

14-
<PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="6.0.0" />
15-
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="6.0.0" />
16-
<PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="6.0.0" />
17-
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="6.0.0" />
18-
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.0" />
15+
<PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="8.0.0" />
16+
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="8.0.0" />
17+
<PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="8.0.0" />
18+
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="8.0.0" />
19+
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.0" />
1920
</ItemGroup>
2021
</Project>

src/IdentityServerAspNetIdentity/Pages/Account/AccessDenied.cshtml.cs

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
// Copyright (c) Duende Software. All rights reserved.
2+
// See LICENSE in the project root for license information.
3+
14
using Microsoft.AspNetCore.Mvc.RazorPages;
25

36
namespace IdentityServerHost.Pages.Account;
@@ -7,4 +10,4 @@ public class AccessDeniedModel : PageModel
710
public void OnGet()
811
{
912
}
10-
}
13+
}

src/IdentityServerAspNetIdentity/Pages/Account/Login/Index.cshtml.cs

+40-27
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
// Copyright (c) Duende Software. All rights reserved.
2+
// See LICENSE in the project root for license information.
3+
4+
using Duende.IdentityServer;
15
using Duende.IdentityServer.Events;
26
using Duende.IdentityServer.Models;
37
using Duende.IdentityServer.Services;
@@ -22,10 +26,10 @@ public class Index : PageModel
2226
private readonly IAuthenticationSchemeProvider _schemeProvider;
2327
private readonly IIdentityProviderStore _identityProviderStore;
2428

25-
public ViewModel View { get; set; }
29+
public ViewModel View { get; set; } = default!;
2630

2731
[BindProperty]
28-
public InputModel Input { get; set; }
32+
public InputModel Input { get; set; } = default!;
2933

3034
public Index(
3135
IIdentityServerInteractionService interaction,
@@ -42,8 +46,8 @@ public Index(
4246
_identityProviderStore = identityProviderStore;
4347
_events = events;
4448
}
45-
46-
public async Task<IActionResult> OnGet(string returnUrl)
49+
50+
public async Task<IActionResult> OnGet(string? returnUrl)
4751
{
4852
await BuildModelAsync(returnUrl);
4953

@@ -66,6 +70,9 @@ public async Task<IActionResult> OnPost()
6670
{
6771
if (context != null)
6872
{
73+
// This "can't happen", because if the ReturnUrl was null, then the context would be null
74+
ArgumentNullException.ThrowIfNull(Input.ReturnUrl, nameof(Input.ReturnUrl));
75+
6976
// if the user cancels, send a result back into IdentityServer as if they
7077
// denied the consent (even if this client does not require consent).
7178
// this will send back an access denied OIDC error response to the client.
@@ -79,7 +86,7 @@ public async Task<IActionResult> OnPost()
7986
return this.LoadingPage(Input.ReturnUrl);
8087
}
8188

82-
return Redirect(Input.ReturnUrl);
89+
return Redirect(Input.ReturnUrl ?? "~/");
8390
}
8491
else
8592
{
@@ -90,14 +97,18 @@ public async Task<IActionResult> OnPost()
9097

9198
if (ModelState.IsValid)
9299
{
93-
var result = await _signInManager.PasswordSignInAsync(Input.Username, Input.Password, Input.RememberLogin, lockoutOnFailure: true);
100+
var result = await _signInManager.PasswordSignInAsync(Input.Username!, Input.Password!, Input.RememberLogin, lockoutOnFailure: true);
94101
if (result.Succeeded)
95102
{
96-
var user = await _userManager.FindByNameAsync(Input.Username);
97-
await _events.RaiseAsync(new UserLoginSuccessEvent(user.UserName, user.Id, user.UserName, clientId: context?.Client.ClientId));
103+
var user = await _userManager.FindByNameAsync(Input.Username!);
104+
await _events.RaiseAsync(new UserLoginSuccessEvent(user!.UserName, user.Id, user.UserName, clientId: context?.Client.ClientId));
105+
Telemetry.Metrics.UserLogin(context?.Client.ClientId, IdentityServerConstants.LocalIdentityProvider);
98106

99107
if (context != null)
100108
{
109+
// This "can't happen", because if the ReturnUrl was null, then the context would be null
110+
ArgumentNullException.ThrowIfNull(Input.ReturnUrl, nameof(Input.ReturnUrl));
111+
101112
if (context.IsNativeClient())
102113
{
103114
// The client is native, so this change in how to
@@ -106,7 +117,7 @@ public async Task<IActionResult> OnPost()
106117
}
107118

108119
// we can trust model.ReturnUrl since GetAuthorizationContextAsync returned non-null
109-
return Redirect(Input.ReturnUrl);
120+
return Redirect(Input.ReturnUrl ?? "~/");
110121
}
111122

112123
// request for a local page
@@ -121,20 +132,22 @@ public async Task<IActionResult> OnPost()
121132
else
122133
{
123134
// user might have clicked on a malicious link - should be logged
124-
throw new Exception("invalid return URL");
135+
throw new ArgumentException("invalid return URL");
125136
}
126137
}
127138

128-
await _events.RaiseAsync(new UserLoginFailureEvent(Input.Username, "invalid credentials", clientId:context?.Client.ClientId));
139+
const string error = "invalid credentials";
140+
await _events.RaiseAsync(new UserLoginFailureEvent(Input.Username, error, clientId:context?.Client.ClientId));
141+
Telemetry.Metrics.UserLoginFailure(context?.Client.ClientId, IdentityServerConstants.LocalIdentityProvider, error);
129142
ModelState.AddModelError(string.Empty, LoginOptions.InvalidCredentialsErrorMessage);
130143
}
131144

132145
// something went wrong, show form with error
133146
await BuildModelAsync(Input.ReturnUrl);
134147
return Page();
135148
}
136-
137-
private async Task BuildModelAsync(string returnUrl)
149+
150+
private async Task BuildModelAsync(string? returnUrl)
138151
{
139152
Input = new InputModel
140153
{
@@ -152,11 +165,11 @@ private async Task BuildModelAsync(string returnUrl)
152165
EnableLocalLogin = local,
153166
};
154167

155-
Input.Username = context?.LoginHint;
168+
Input.Username = context.LoginHint;
156169

157170
if (!local)
158171
{
159-
View.ExternalProviders = new[] { new ViewModel.ExternalProvider { AuthenticationScheme = context.IdP } };
172+
View.ExternalProviders = new[] { new ViewModel.ExternalProvider ( authenticationScheme: context.IdP ) };
160173
}
161174

162175
return;
@@ -167,27 +180,27 @@ private async Task BuildModelAsync(string returnUrl)
167180
var providers = schemes
168181
.Where(x => x.DisplayName != null)
169182
.Select(x => new ViewModel.ExternalProvider
170-
{
171-
DisplayName = x.DisplayName ?? x.Name,
172-
AuthenticationScheme = x.Name
173-
}).ToList();
183+
(
184+
authenticationScheme: x.Name,
185+
displayName: x.DisplayName ?? x.Name
186+
)).ToList();
174187

175-
var dyanmicSchemes = (await _identityProviderStore.GetAllSchemeNamesAsync())
188+
var dynamicSchemes = (await _identityProviderStore.GetAllSchemeNamesAsync())
176189
.Where(x => x.Enabled)
177190
.Select(x => new ViewModel.ExternalProvider
178-
{
179-
AuthenticationScheme = x.Scheme,
180-
DisplayName = x.DisplayName
181-
});
182-
providers.AddRange(dyanmicSchemes);
191+
(
192+
authenticationScheme: x.Scheme,
193+
displayName: x.DisplayName ?? x.Scheme
194+
));
195+
providers.AddRange(dynamicSchemes);
183196

184197

185198
var allowLocal = true;
186199
var client = context?.Client;
187200
if (client != null)
188201
{
189202
allowLocal = client.EnableLocalLogin;
190-
if (client.IdentityProviderRestrictions != null && client.IdentityProviderRestrictions.Any())
203+
if (client.IdentityProviderRestrictions != null && client.IdentityProviderRestrictions.Count != 0)
191204
{
192205
providers = providers.Where(provider => client.IdentityProviderRestrictions.Contains(provider.AuthenticationScheme)).ToList();
193206
}
@@ -200,4 +213,4 @@ private async Task BuildModelAsync(string returnUrl)
200213
ExternalProviders = providers.ToArray()
201214
};
202215
}
203-
}
216+
}
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,17 @@
11
// Copyright (c) Duende Software. All rights reserved.
22
// See LICENSE in the project root for license information.
33

4-
54
using System.ComponentModel.DataAnnotations;
65

76
namespace IdentityServerHost.Pages.Login;
87

98
public class InputModel
109
{
1110
[Required]
12-
public string Username { get; set; }
13-
11+
public string? Username { get; set; }
1412
[Required]
15-
public string Password { get; set; }
16-
13+
public string? Password { get; set; }
1714
public bool RememberLogin { get; set; }
18-
19-
public string ReturnUrl { get; set; }
20-
21-
public string Button { get; set; }
15+
public string? ReturnUrl { get; set; }
16+
public string? Button { get; set; }
2217
}
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
1+
// Copyright (c) Duende Software. All rights reserved.
2+
// See LICENSE in the project root for license information.
3+
14
namespace IdentityServerHost.Pages.Login;
25

3-
public class LoginOptions
6+
public static class LoginOptions
47
{
5-
public static bool AllowLocalLogin = true;
6-
public static bool AllowRememberLogin = true;
7-
public static TimeSpan RememberMeLoginDuration = TimeSpan.FromDays(30);
8-
public static string InvalidCredentialsErrorMessage = "Invalid username or password";
8+
public static readonly bool AllowLocalLogin = true;
9+
public static readonly bool AllowRememberLogin = true;
10+
public static readonly TimeSpan RememberMeLoginDuration = TimeSpan.FromDays(30);
11+
public static readonly string InvalidCredentialsErrorMessage = "Invalid username or password";
912
}

src/IdentityServerAspNetIdentity/Pages/Account/Login/ViewModel.cs

+8-2
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,17 @@ public class ViewModel
1212
public IEnumerable<ViewModel.ExternalProvider> VisibleExternalProviders => ExternalProviders.Where(x => !String.IsNullOrWhiteSpace(x.DisplayName));
1313

1414
public bool IsExternalLoginOnly => EnableLocalLogin == false && ExternalProviders?.Count() == 1;
15-
public string ExternalLoginScheme => IsExternalLoginOnly ? ExternalProviders?.SingleOrDefault()?.AuthenticationScheme : null;
15+
public string? ExternalLoginScheme => IsExternalLoginOnly ? ExternalProviders?.SingleOrDefault()?.AuthenticationScheme : null;
1616

1717
public class ExternalProvider
1818
{
19-
public string DisplayName { get; set; }
19+
public ExternalProvider(string authenticationScheme, string? displayName = null)
20+
{
21+
AuthenticationScheme = authenticationScheme;
22+
DisplayName = displayName;
23+
}
24+
25+
public string? DisplayName { get; set; }
2026
public string AuthenticationScheme { get; set; }
2127
}
2228
}

0 commit comments

Comments
 (0)