Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace IdentityServer4 with Duende.IdentityServer (#3008) #3184

Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 7 additions & 10 deletions test/WebSites/OAuth2Integration/AuthServer/Config.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using System.Collections.Generic;
using IdentityServer4.Models;
using IdentityServer4.Test;
using Duende.IdentityServer.Models;
using Duende.IdentityServer.Test;

namespace OAuth2Integration.AuthServer
{
Expand Down Expand Up @@ -31,15 +31,12 @@ internal static IEnumerable<Client> Clients()

internal static IEnumerable<ApiResource> ApiResources()
{
yield return new ApiResource
return new List<ApiResource>
{
Name = "api",
DisplayName = "API",
Scopes =
[
new Scope("readAccess", "Access read operations"),
new Scope("writeAccess", "Access write operations")
]
new ApiResource("api", "API")
{
Scopes = { "readAccess", "writeAccess" }
}
};
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Duende.IdentityServer;
using Duende.IdentityServer.Test;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using IdentityServer4;
using IdentityServer4.Test;
using Microsoft.AspNetCore.Mvc;

namespace OAuth2Integration.AuthServer.Controllers
{
Expand All @@ -22,12 +22,11 @@ public AccountController()
public IActionResult Login(string returnUrl)
{
var viewModel = new LoginViewModel { Username = "joebloggs", Password = "pass123", ReturnUrl = returnUrl };

return View("/AuthServer/Views/Login.cshtml", viewModel);
}

[HttpPost("login")]
public async Task<IActionResult> Login([FromForm]LoginViewModel viewModel)
public async Task<IActionResult> Login([FromForm] LoginViewModel viewModel)
{
if (!_userStore.ValidateCredentials(viewModel.Username, viewModel.Password))
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using IdentityServer4.Models;
using IdentityServer4.Services;
using IdentityServer4.Stores;
using Duende.IdentityServer.Models;
using Duende.IdentityServer.Services;
using Duende.IdentityServer.Stores;
using Microsoft.AspNetCore.Mvc;

namespace OAuth2Integration.AuthServer.Controllers
Expand All @@ -12,46 +12,50 @@ namespace OAuth2Integration.AuthServer.Controllers
public class ConsentController : Controller
{
private readonly IIdentityServerInteractionService _interaction;
private readonly IClientStore _clientStore;
private readonly IResourceStore _resourceStore;

public ConsentController(
IIdentityServerInteractionService interaction,
IClientStore clientStore,
IResourceStore resourceStore)
IIdentityServerInteractionService interaction)
{
_interaction = interaction;
_clientStore = clientStore;
_resourceStore = resourceStore;
}

[HttpGet("consent")]
public async Task<IActionResult> Consent(string returnUrl)
{
var request = await _interaction.GetAuthorizationContextAsync(returnUrl);
var client = await _clientStore.FindEnabledClientByIdAsync(request.ClientId);
var resource = await _resourceStore.FindApiResourceAsync("api");

var viewModel = new ConsentViewModel
{
ReturnUrl = returnUrl,
ClientName = client.ClientName,
ScopesRequested = resource.Scopes.Where(s => request.ScopesRequested.Contains(s.Name))
ClientName = request.Client.ClientName,
ScopesRequested = request.ValidatedResources?.Resources?.ApiScopes ?? new List<ApiScope>()
};

return View("/AuthServer/Views/Consent.cshtml", viewModel);
}

[HttpPost("consent")]
public async Task<IActionResult> Consent([FromForm]ConsentViewModel viewModel)
public async Task<IActionResult> Consent([FromForm] ConsentViewModel viewModel)
{
var request = await _interaction.GetAuthorizationContextAsync(viewModel.ReturnUrl);

// Communicate outcome of consent back to identityserver
var consentResponse = new ConsentResponse
ConsentResponse consentResponse;
if (viewModel.ScopesConsented != null && viewModel.ScopesConsented.Any())
{
ScopesConsented = viewModel.ScopesConsented
};
consentResponse = new ConsentResponse
{
RememberConsent = true,
ScopesValuesConsented = viewModel.ScopesConsented.ToList()
};
}
else
{
consentResponse = new ConsentResponse
{
Error = AuthorizationError.AccessDenied
};
}

await _interaction.GrantConsentAsync(request, consentResponse);

return Redirect(viewModel.ReturnUrl);
Expand All @@ -62,7 +66,7 @@ public class ConsentViewModel
{
public string ReturnUrl { get; set; }
public string ClientName { get; set; }
public IEnumerable<Scope> ScopesRequested { get; set; }
public IEnumerable<ApiScope> ScopesRequested { get; set; }
public string[] ScopesConsented { get; set; }
}
}
29 changes: 16 additions & 13 deletions test/WebSites/OAuth2Integration/OAuth2Integration.csproj
Original file line number Diff line number Diff line change
@@ -1,26 +1,29 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFrameworks>net9.0;net8.0;net6.0</TargetFrameworks>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="IdentityServer4" />
<PackageReference Include="IdentityServer4.AccessTokenValidation" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\..\src\Swashbuckle.AspNetCore.Swagger\Swashbuckle.AspNetCore.Swagger.csproj" />
<ProjectReference Include="..\..\..\src\Swashbuckle.AspNetCore.SwaggerGen\Swashbuckle.AspNetCore.SwaggerGen.csproj" />
<ProjectReference Include="..\..\..\src\Swashbuckle.AspNetCore.SwaggerUI\Swashbuckle.AspNetCore.SwaggerUI.csproj" />
</ItemGroup>

<!--
This is just a sample for testing - updating to Duende.IdentityServer can be done at some point in the future.
See /~https://github.com/domaindrivendev/Swashbuckle.AspNetCore/issues/3008.
-->
<ItemGroup>
<NuGetAuditSuppress Include="/~https://github.com/advisories/GHSA-55p7-v223-x366" />
<NuGetAuditSuppress Include="/~https://github.com/advisories/GHSA-ff4q-64jc-gx98" />

<ItemGroup Condition="'$(TargetFramework)' == 'net6.0'">
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" VersionOverride="6.0.5" />
<PackageReference Include="Duende.IdentityServer" VersionOverride="6.0.5" />
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'net8.0'">
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" VersionOverride="8.0.11" />
<PackageReference Include="Duende.IdentityServer" VersionOverride="7.0.8" />
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'net9.0'">
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" VersionOverride="8.0.11" />
<PackageReference Include="Duende.IdentityServer" VersionOverride="7.0.8" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

namespace OAuth2Integration.ResourceServer.Controllers
{
Expand Down Expand Up @@ -33,7 +33,7 @@ public Product GetProduct(int id)

[HttpPost]
[Authorize("writeAccess")]
public void CreateProduct([FromBody]Product product)
public void CreateProduct([FromBody] Product product)
{
}

Expand All @@ -53,6 +53,6 @@ public class Product

public enum ProductStatus
{
InStock, ComingSoon
InStock, ComingSoon
}
}
}
19 changes: 13 additions & 6 deletions test/WebSites/OAuth2Integration/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
using System.Collections.Generic;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.DataProtection;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
Expand All @@ -24,7 +23,7 @@ public Startup(IConfiguration configuration)
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
// Register IdentityServer services to power OAuth2.0 flows
// Register Duende IdentityServer services to power OAuth2.0 flows
services.AddIdentityServer()
.AddDeveloperSigningCredential()
.AddInMemoryClients(AuthServer.Config.Clients())
Expand All @@ -36,11 +35,19 @@ public void ConfigureServices(IServiceCollection services)
// See https://learn.microsoft.com/aspnet/core/security/authorization/limitingidentitybyscheme
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie()
.AddIdentityServerAuthentication(c =>
.AddJwtBearer("Bearer", options =>
{
c.Authority = "https://localhost:5001/auth-server/";
c.RequireHttpsMetadata = false;
c.ApiName = "api";
options.Authority = "https://localhost:5001/auth-server/";
options.RequireHttpsMetadata = false;
options.Audience = "api";
options.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidAudience = "api",
ValidIssuer = "https://localhost:5001/auth-server/",
};
});

// Configure named auth policies that map directly to OAuth2.0 scopes
Expand Down
Loading