-
Notifications
You must be signed in to change notification settings - Fork 272
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #166 from DuendeSoftware/joe/token-exchange-net8
TokenExchange - Update to .NET 8
- Loading branch information
Showing
19 changed files
with
354 additions
and
287 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
{ | ||
"version": "0.2.0", | ||
"compounds": [ | ||
{ | ||
"name": "Run All", | ||
"configurations": ["IdentityServerHost", "Client"], | ||
"presentation": { | ||
"group": "10-compunds", | ||
} | ||
} | ||
], | ||
"configurations": [ | ||
{ | ||
"name": "IdentityServerHost", | ||
"type": "coreclr", | ||
"request": "launch", | ||
"preLaunchTask": "build-identityserverhost", | ||
"program": "${workspaceFolder}/IdentityServerHost/bin/Debug/net8.0/IdentityServerHost.dll", | ||
"args": [], | ||
"cwd": "${workspaceFolder}/IdentityServerHost", | ||
"env": { | ||
"ASPNETCORE_ENVIRONMENT": "Development" | ||
}, | ||
"console": "externalTerminal", | ||
}, | ||
{ | ||
"name": "Client", | ||
"type": "coreclr", | ||
"request": "launch", | ||
"preLaunchTask": "build-client", | ||
"program": "${workspaceFolder}/Client/bin/Debug/net8.0/Client.dll", | ||
"args": [], | ||
"cwd": "${workspaceFolder}/Client", | ||
"console": "externalTerminal", | ||
"env": { | ||
"ASPNETCORE_ENVIRONMENT": "Development" | ||
}, | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
{ | ||
"version": "2.0.0", | ||
"tasks": [ | ||
{ | ||
"label": "build", | ||
"type": "process", | ||
"command": "dotnet", | ||
"args": [ | ||
"build", | ||
"${workspaceFolder}/TokenExchange.sln", | ||
"/property:GenerateFullPaths=true", | ||
"/consoleloggerparameters:NoSummary" | ||
], | ||
"problemMatcher": "$msCompile" | ||
}, | ||
{ | ||
"label": "build-identityserverhost", | ||
"type": "process", | ||
"command": "dotnet", | ||
"args": [ | ||
"build", | ||
"${workspaceFolder}/IdentityServerHost", | ||
"/property:GenerateFullPaths=true", | ||
"/consoleloggerparameters:NoSummary" | ||
], | ||
"problemMatcher": "$msCompile" | ||
}, | ||
{ | ||
"label": "build-client", | ||
"type": "process", | ||
"command": "dotnet", | ||
"args": [ | ||
"build", | ||
"${workspaceFolder}/Client", | ||
"/property:GenerateFullPaths=true", | ||
"/consoleloggerparameters:NoSummary" | ||
], | ||
"problemMatcher": "$msCompile" | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
50 changes: 50 additions & 0 deletions
50
IdentityServer/v7/TokenExchange/IdentityServerHost/Config.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
// Copyright (c) Duende Software. All rights reserved. | ||
// See LICENSE in the project root for license information. | ||
|
||
|
||
using Duende.IdentityServer.Models; | ||
using System.Collections.Generic; | ||
using IdentityModel; | ||
|
||
namespace IdentityServerHost; | ||
|
||
public static class Config | ||
{ | ||
public static readonly IEnumerable<ApiScope> Scopes = | ||
new[] | ||
{ | ||
new ApiScope("scope1"), | ||
new ApiScope("scope2"), | ||
}; | ||
|
||
public static IEnumerable<Client> Clients => | ||
new [] | ||
{ | ||
// represent the front end client | ||
new Client | ||
{ | ||
ClientId = "front.end", | ||
ClientSecrets = { new Secret("secret".Sha256()) }, | ||
|
||
AllowedGrantTypes = GrantTypes.ClientCredentials, | ||
AllowedScopes = { "scope1" }, | ||
|
||
// simulate interactive user | ||
ClientClaimsPrefix = "", | ||
Claims = | ||
{ | ||
new ClientClaim("sub", "123") | ||
} | ||
}, | ||
|
||
// represents the client that is delegating the access token | ||
new Client | ||
{ | ||
ClientId = "api1", | ||
ClientSecrets = { new Secret("secret".Sha256()) }, | ||
|
||
AllowedGrantTypes = { OidcConstants.GrantTypes.TokenExchange }, | ||
AllowedScopes = { "scope2" } | ||
} | ||
}; | ||
} |
11 changes: 11 additions & 0 deletions
11
IdentityServer/v7/TokenExchange/IdentityServerHost/IdentityServerHost.csproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
<Project Sdk="Microsoft.NET.Sdk.Web"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>net8.0</TargetFramework> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Duende.IdentityServer" Version="7.0.0-rc.2" /> | ||
<PackageReference Include="Serilog.AspNetCore" Version="8.0.0" /> | ||
</ItemGroup> | ||
</Project> |
32 changes: 32 additions & 0 deletions
32
IdentityServer/v7/TokenExchange/IdentityServerHost/ProfileService.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
using System.Linq; | ||
using System.Threading.Tasks; | ||
using Duende.IdentityServer.Extensions; | ||
using Duende.IdentityServer.Models; | ||
using Duende.IdentityServer.Services; | ||
using IdentityModel; | ||
|
||
namespace IdentityServerHost; | ||
|
||
public class ProfileService : IProfileService | ||
{ | ||
public Task GetProfileDataAsync(ProfileDataRequestContext context) | ||
{ | ||
// add actor claim if needed | ||
if (context.Subject.GetAuthenticationMethod() == OidcConstants.GrantTypes.TokenExchange) | ||
{ | ||
var act = context.Subject.FindFirst(JwtClaimTypes.Actor); | ||
if (act != null) | ||
{ | ||
context.IssuedClaims.Add(act); | ||
} | ||
} | ||
|
||
return Task.CompletedTask; | ||
} | ||
|
||
public Task IsActiveAsync(IsActiveContext context) | ||
{ | ||
context.IsActive = true; | ||
return Task.CompletedTask; | ||
} | ||
} |
48 changes: 48 additions & 0 deletions
48
IdentityServer/v7/TokenExchange/IdentityServerHost/Program.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
// Copyright (c) Duende Software. All rights reserved. | ||
// See LICENSE in the project root for license information. | ||
|
||
|
||
using Microsoft.AspNetCore.Hosting; | ||
using Microsoft.Extensions.Hosting; | ||
using Serilog; | ||
using Serilog.Events; | ||
using Serilog.Sinks.SystemConsole.Themes; | ||
using System; | ||
|
||
namespace IdentityServerHost; | ||
|
||
public class Program | ||
{ | ||
public static int Main(string[] args) | ||
{ | ||
Log.Logger = new LoggerConfiguration() | ||
.MinimumLevel.Information() | ||
.Enrich.FromLogContext() | ||
.WriteTo.Console(outputTemplate: "[{Timestamp:HH:mm:ss} {Level}] {SourceContext}{NewLine}{Message:lj}{NewLine}{Exception}{NewLine}", theme: AnsiConsoleTheme.Code) | ||
.CreateLogger(); | ||
|
||
try | ||
{ | ||
Log.Information("Starting host..."); | ||
CreateHostBuilder(args).Build().Run(); | ||
return 0; | ||
} | ||
catch (Exception ex) | ||
{ | ||
Log.Fatal(ex, "Host terminated unexpectedly."); | ||
return 1; | ||
} | ||
finally | ||
{ | ||
Log.CloseAndFlush(); | ||
} | ||
} | ||
|
||
public static IHostBuilder CreateHostBuilder(string[] args) => | ||
Host.CreateDefaultBuilder(args) | ||
.UseSerilog() | ||
.ConfigureWebHostDefaults(webBuilder => | ||
{ | ||
webBuilder.UseStartup<Startup>(); | ||
}); | ||
} |
File renamed without changes.
33 changes: 33 additions & 0 deletions
33
IdentityServer/v7/TokenExchange/IdentityServerHost/Startup.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
// Copyright (c) Duende Software. All rights reserved. | ||
// See LICENSE in the project root for license information. | ||
|
||
using System; | ||
using Microsoft.AspNetCore.Builder; | ||
using Microsoft.Extensions.DependencyInjection; | ||
|
||
namespace IdentityServerHost; | ||
|
||
public class Startup | ||
{ | ||
public void ConfigureServices(IServiceCollection services) | ||
{ | ||
Console.Title = "IdentityServer"; | ||
|
||
var builder = services.AddIdentityServer() | ||
.AddInMemoryApiScopes(Config.Scopes) | ||
.AddInMemoryClients(Config.Clients); | ||
|
||
// registers extension grant validator for the token exchange grant type | ||
builder.AddExtensionGrantValidator<TokenExchangeGrantValidator>(); | ||
|
||
// register a profile service to emit the act claim | ||
builder.AddProfileService<ProfileService>(); | ||
} | ||
|
||
public void Configure(IApplicationBuilder app) | ||
{ | ||
app.UseDeveloperExceptionPage(); | ||
|
||
app.UseIdentityServer(); | ||
} | ||
} |
94 changes: 94 additions & 0 deletions
94
IdentityServer/v7/TokenExchange/IdentityServerHost/TokenExchangeGrantValidator.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Security.Claims; | ||
using System.Text.Json; | ||
using System.Threading.Tasks; | ||
using Duende.IdentityServer; | ||
using Duende.IdentityServer.Models; | ||
using Duende.IdentityServer.Validation; | ||
using IdentityModel; | ||
|
||
namespace IdentityServerHost; | ||
|
||
public class TokenExchangeGrantValidator : IExtensionGrantValidator | ||
{ | ||
private readonly ITokenValidator _validator; | ||
|
||
public TokenExchangeGrantValidator(ITokenValidator validator) | ||
{ | ||
_validator = validator; | ||
} | ||
|
||
public async Task ValidateAsync(ExtensionGrantValidationContext context) | ||
{ | ||
// defaults | ||
context.Result = new GrantValidationResult(TokenRequestErrors.InvalidRequest); | ||
var customResponse = new Dictionary<string, object> | ||
{ | ||
{OidcConstants.TokenResponse.IssuedTokenType, OidcConstants.TokenTypeIdentifiers.AccessToken} | ||
}; | ||
|
||
var subjectToken = context.Request.Raw.Get(OidcConstants.TokenRequest.SubjectToken); | ||
var subjectTokenType = context.Request.Raw.Get(OidcConstants.TokenRequest.SubjectTokenType); | ||
|
||
// mandatory parameters | ||
if (string.IsNullOrWhiteSpace(subjectToken)) | ||
{ | ||
return; | ||
} | ||
|
||
if (!string.Equals(subjectTokenType, OidcConstants.TokenTypeIdentifiers.AccessToken)) | ||
{ | ||
return; | ||
} | ||
|
||
var validationResult = await _validator.ValidateAccessTokenAsync(subjectToken); | ||
if (validationResult.IsError) | ||
{ | ||
return; | ||
} | ||
|
||
var sub = validationResult.Claims.First(c => c.Type == JwtClaimTypes.Subject).Value; | ||
var clientId = validationResult.Claims.First(c => c.Type == JwtClaimTypes.ClientId).Value; | ||
|
||
var style = context.Request.Raw.Get("exchange_style"); | ||
|
||
if (style == "impersonation") | ||
{ | ||
// set token client_id to original id | ||
context.Request.ClientId = clientId; | ||
|
||
context.Result = new GrantValidationResult( | ||
subject: sub, | ||
authenticationMethod: GrantType, | ||
customResponse: customResponse); | ||
} | ||
else if (style == "delegation") | ||
{ | ||
// set token client_id to original id | ||
context.Request.ClientId = clientId; | ||
|
||
var actor = new | ||
{ | ||
client_id = context.Request.Client.ClientId | ||
}; | ||
|
||
var actClaim = new Claim(JwtClaimTypes.Actor, JsonSerializer.Serialize(actor), IdentityServerConstants.ClaimValueTypes.Json); | ||
|
||
context.Result = new GrantValidationResult( | ||
subject: sub, | ||
authenticationMethod: GrantType, | ||
claims: new[] { actClaim }, | ||
customResponse: customResponse); | ||
} | ||
else if (style == "custom") | ||
{ | ||
context.Result = new GrantValidationResult( | ||
subject: sub, | ||
authenticationMethod: GrantType, | ||
customResponse: customResponse); | ||
} | ||
} | ||
|
||
public string GrantType => OidcConstants.GrantTypes.TokenExchange; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.