Skip to content

Commit

Permalink
Allow API access with a token from Authorize access (#1274)
Browse files Browse the repository at this point in the history
  • Loading branch information
gunndabad authored Apr 10, 2024
1 parent e579671 commit a414abc
Show file tree
Hide file tree
Showing 6 changed files with 42 additions and 16 deletions.
19 changes: 15 additions & 4 deletions TeachingRecordSystem/src/TeachingRecordSystem.Api/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
using FluentValidation;
using FluentValidation.AspNetCore;
using idunno.Authentication.Basic;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ApiExplorer;
using Microsoft.AspNetCore.Mvc.Formatters;
Expand Down Expand Up @@ -48,12 +47,18 @@ public static void Main(string[] args)

services.AddAuthentication(ApiKeyAuthenticationHandler.AuthenticationScheme)
.AddScheme<ApiKeyAuthenticationOptions, ApiKeyAuthenticationHandler>(ApiKeyAuthenticationHandler.AuthenticationScheme, _ => { })
.AddJwtBearer(options =>
.AddJwtBearer(AuthenticationSchemeNames.IdAccessToken, options =>
{
options.Authority = configuration["GetAnIdentity:BaseAddress"];
options.MapInboundClaims = false;
options.TokenValidationParameters.ValidateAudience = false;
})
.AddJwtBearer(AuthenticationSchemeNames.AuthorizeAccessAccessToken, options =>
{
options.Authority = configuration.GetRequiredValue("AuthorizeAccessIssuer");
options.MapInboundClaims = false;
options.TokenValidationParameters.ValidateAudience = false;
})
.AddBasic(options =>
{
options.Realm = "TeachingRecordSystem.Api";
Expand Down Expand Up @@ -101,11 +106,11 @@ public static void Main(string[] args)
options.AddPolicy(
AuthorizationPolicies.IdentityUserWithTrn,
policy => policy
.AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme)
.AddAuthenticationSchemes(AuthenticationSchemeNames.IdAccessToken, AuthenticationSchemeNames.AuthorizeAccessAccessToken)
.RequireAssertion(ctx =>
{
var scopes = (ctx.User.FindFirstValue("scope") ?? string.Empty).Split(' ', StringSplitOptions.RemoveEmptyEntries);
return scopes.Contains("dqt:read");
return scopes.Contains("dqt:read") || scopes.Contains("teaching_record");
})
.RequireClaim("trn"));

Expand Down Expand Up @@ -298,3 +303,9 @@ ServiceClient GetCrmServiceClient()
}
}
}

file static class AuthenticationSchemeNames
{
public const string IdAccessToken = nameof(IdAccessToken);
public const string AuthorizeAccessAccessToken = nameof(AuthorizeAccessAccessToken);
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"AllowVNextEndpoints": true,
"AuthorizeAccessIssuer": "https://localhost:7236",
"DetailedErrors": true,
"Serilog": {
"MinimumLevel": {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"AllowVNextEndpoints": true,
"AuthorizeAccessIssuer": "https://dummy",
"Serilog": {
"MinimumLevel": {
"Default": "Error",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,23 @@
@using TeachingRecordSystem.AuthorizeAccess.Pages.OidcTest
@addTagHelper *, Joonasw.AspNetCore.SecurityHeaders
@model SignedInModel
@{
var claimsJson = JsonSerializer.Serialize(
User.Claims.ToDictionary(c => c.Type, c => c.Value),
new JsonSerializerOptions() { WriteIndented = true });
}

@section Styles {
<style type="text/css" asp-add-nonce="true">
.claims-json {
font-family: monospace !important;
white-space: nowrap;
height: 260px;
white-space: pre-wrap;
}
.access-token {
font-family: monospace !important;
}
</style>
}

<p class="govuk-body">
<govuk-textarea name="Claims" textarea-class="claims-json">
<govuk-textarea-label>Claims</govuk-textarea-label>
<govuk-textarea-value>@claimsJson</govuk-textarea-value>
</govuk-textarea>
<govuk-input asp-for="AccessToken" input-class="access-token" disabled="true" />

<govuk-textarea asp-for="ClaimsJson" textarea-class="claims-json" disabled="true" />
</p>
Original file line number Diff line number Diff line change
@@ -1,12 +1,27 @@
using System.ComponentModel.DataAnnotations;
using System.Text.Json;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc.RazorPages;
using static IdentityModel.OidcConstants;

namespace TeachingRecordSystem.AuthorizeAccess.Pages.OidcTest;

[Authorize(AuthenticationSchemes = TestAppConfiguration.AuthenticationSchemeName)]
public class SignedInModel : PageModel
{
public void OnGet()
[Display(Name = "Access token")]
public string? AccessToken { get; set; }

[Display(Name = "Claims")]
public string? ClaimsJson { get; set; }

public async Task OnGet()
{
AccessToken = await HttpContext.GetTokenAsync(TestAppConfiguration.AuthenticationSchemeName, TokenTypes.AccessToken);

ClaimsJson = JsonSerializer.Serialize(
User.Claims.ToDictionary(c => c.Type, c => c.Value),
new JsonSerializerOptions() { WriteIndented = true });
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ protected override void ConfigureWebHost(IWebHostBuilder builder)
.AddHttpMessageHandler(_ => EvidenceFilesHttpClientInterceptorOptions.CreateHttpMessageHandler())
.ConfigurePrimaryHttpMessageHandler(_ => new NotFoundHandler());

services.PostConfigure<JwtBearerOptions>(JwtBearerDefaults.AuthenticationScheme, options =>
services.PostConfigure<JwtBearerOptions>("IdAccessToken", options =>
{
options.TokenValidationParameters.ValidateIssuer = false;
options.TokenValidationParameters.IssuerSigningKey = JwtSigningCredentials.Key;
Expand Down

0 comments on commit a414abc

Please sign in to comment.