Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
6 changes: 3 additions & 3 deletions authorization-dotnet/DecodeJwt/App/App.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="IdentityModel" Version="6.2.0"/>
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="7.0.3"/>
<PackageReference Include="Duende.IdentityModel" Version="8.1.0"/>
<PackageReference Include="Microsoft.IdentityModel.JsonWebTokens" Version="8.23.0"/>
</ItemGroup>

</Project>
35 changes: 23 additions & 12 deletions authorization-dotnet/DecodeJwt/App/JwtUtils.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using System.IdentityModel.Tokens.Jwt;
using IdentityModel.Client;
using System.Buffers.Text;
using System.Text;
using Duende.IdentityModel.Client;
using Microsoft.IdentityModel.JsonWebTokens;

namespace App;

Expand All @@ -20,25 +22,25 @@ public static class JwtUtils
{ Address = discoveryDocument.TokenEndpoint, ClientId = "m2m", ClientSecret = "secret", Scope = "api" });
}

if (tokenResponse.IsError)
if (tokenResponse.IsError)
{
throw new Exception(tokenResponse.Error);
}

return tokenResponse.AccessToken;
}

public static JwtSecurityToken ConvertJwtStringToJwtSecurityToken(string? jwt)
public static JsonWebToken ConvertJwtStringToJsonWebToken(string jwt)
{
var handler = new JwtSecurityTokenHandler();
var token = handler.ReadJwtToken(jwt);
var handler = new JsonWebTokenHandler();
var token = handler.ReadJsonWebToken(jwt);

return token;
}

public static DecodedToken DecodeJwt(JwtSecurityToken token)
public static DecodedToken DecodeJwt(JsonWebToken token)
{
var keyId = token.Header.Kid;
var keyId = token.Kid;
var audience = token.Audiences.ToList();
var claims = token.Claims.Select(claim => (claim.Type, claim.Value)).ToList();

Expand All @@ -48,12 +50,21 @@ public static DecodedToken DecodeJwt(JwtSecurityToken token)
audience,
claims,
token.ValidTo,
token.SignatureAlgorithm,
token.RawData,
token.Alg,
token.EncodedToken,
token.Subject,
token.ValidFrom,
token.EncodedHeader,
token.EncodedPayload
);
}

public static (string Header, string Payload) DecodeJwtWithoutLibrary(string jwt)
{
var parts = jwt.Split('.');
var header = Encoding.UTF8.GetString(Base64Url.DecodeFromChars(parts[0]));
var payload = Encoding.UTF8.GetString(Base64Url.DecodeFromChars(parts[1]));

return (header, payload);
}
}
8 changes: 6 additions & 2 deletions authorization-dotnet/DecodeJwt/App/Program.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
using App;

var accessToken = await JwtUtils.GetAccessTokenFromDuendeIdentityServerAsync();
var accessToken = await JwtUtils.GetAccessTokenFromDuendeIdentityServerAsync()
?? throw new InvalidOperationException("The token endpoint returned no access token.");
Console.WriteLine(accessToken);
var jwt = JwtUtils.ConvertJwtStringToJwtSecurityToken(accessToken);
var jwt = JwtUtils.ConvertJwtStringToJsonWebToken(accessToken);
Console.WriteLine(jwt);
var jwtData = JwtUtils.DecodeJwt(jwt);
Console.WriteLine(jwtData);
var (header, payload) = JwtUtils.DecodeJwtWithoutLibrary(accessToken);
Console.WriteLine(header);
Console.WriteLine(payload);
16 changes: 13 additions & 3 deletions authorization-dotnet/DecodeJwt/Tests/DecodeJwtTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ namespace Tests;
public class DecodeJwtTest
{
[Fact]
public async Task WhenJwtIsRetrievedFromServer_ThenItShouldNotBeNull()
public async Task WhenJwtIsRetrievedFromServer_ThenItShouldNotBeNull_Live()
{
var jwt = await JwtUtils.GetAccessTokenFromDuendeIdentityServerAsync();

Expand All @@ -14,11 +14,21 @@ public async Task WhenJwtIsRetrievedFromServer_ThenItShouldNotBeNull()
[ClassData(typeof(JwtTestData))]
public void WhenJwtIsValid_ThenItShouldDecode(string token)
{
var jwt = JwtUtils.ConvertJwtStringToJwtSecurityToken(token);
var jwt = JwtUtils.ConvertJwtStringToJsonWebToken(token);
var jwtData = JwtUtils.DecodeJwt(jwt);

Assert.NotNull(jwtData.Issuer);
Assert.NotEmpty(jwtData.Audience);
Assert.NotEmpty(jwtData.Claims);
}
}

[Theory]
[ClassData(typeof(JwtTestData))]
public void WhenJwtIsDecodedWithoutLibrary_ThenHeaderAndPayloadAreJson(string token)
{
var (header, payload) = JwtUtils.DecodeJwtWithoutLibrary(token);

Assert.Contains("\"alg\":\"RS256\"", header);
Assert.Contains("\"iss\":\"https://demo.duendesoftware.com\"", payload);
}
}
10 changes: 5 additions & 5 deletions authorization-dotnet/DecodeJwt/Tests/Tests.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>

Expand All @@ -10,13 +10,13 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0"/>
<PackageReference Include="xunit" Version="2.6.2"/>
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.4">
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.11.0"/>
<PackageReference Include="xunit" Version="2.9.3"/>
<PackageReference Include="xunit.runner.visualstudio" Version="4.0.1">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="coverlet.collector" Version="6.0.0">
<PackageReference Include="coverlet.collector" Version="10.1.0">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
Expand Down
Loading