108 lines
No EOL
4.2 KiB
C#
108 lines
No EOL
4.2 KiB
C#
using FluentResults;
|
|
using IdentityShroud.Api.Mappers;
|
|
using IdentityShroud.Api.Validation;
|
|
using IdentityShroud.Core.Messages;
|
|
using IdentityShroud.Core.Messages.Realm;
|
|
using IdentityShroud.Core.Model;
|
|
using IdentityShroud.Core.Services;
|
|
using Microsoft.AspNetCore.Http.HttpResults;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
|
|
namespace IdentityShroud.Api;
|
|
|
|
public static class HttpContextExtensions
|
|
{
|
|
public static Realm GetValidatedRealm(this HttpContext context) => (Realm)context.Items["RealmEntity"]!;
|
|
}
|
|
|
|
|
|
|
|
public static class RealmApi
|
|
{
|
|
public static void MapRealmEndpoints(this IEndpointRouteBuilder app)
|
|
{
|
|
var realmsGroup = app.MapGroup("/realms");
|
|
realmsGroup.MapPost("", RealmCreate)
|
|
.Validate<RealmCreateRequest>()
|
|
.WithName("Create Realm")
|
|
.Produces(StatusCodes.Status201Created);
|
|
|
|
var realmSlugGroup = realmsGroup.MapGroup("{slug}")
|
|
.AddEndpointFilter<SlugValidationFilter>();
|
|
realmSlugGroup.MapGet("", GetRealmInfo);
|
|
realmSlugGroup.MapGet(".well-known/openid-configuration", GetOpenIdConfiguration);
|
|
|
|
var openidConnect = realmSlugGroup.MapGroup("openid-connect");
|
|
openidConnect.MapPost("auth", OpenIdConnectAuth);
|
|
openidConnect.MapPost("token", OpenIdConnectToken);
|
|
openidConnect.MapGet("jwks", OpenIdConnectJwks);
|
|
}
|
|
|
|
private static async Task<Results<Created<RealmCreateResponse>, InternalServerError>>
|
|
RealmCreate(RealmCreateRequest request, [FromServices] IRealmService service)
|
|
{
|
|
var response = await service.Create(request);
|
|
if (response.IsSuccess)
|
|
return TypedResults.Created($"/realms/{response.Value.Slug}", response.Value);
|
|
|
|
// TODO make helper to convert failure response to a proper HTTP result.
|
|
return TypedResults.InternalServerError();
|
|
}
|
|
|
|
private static async Task<Results<Ok<JsonWebKeySet>, BadRequest>> OpenIdConnectJwks(
|
|
string slug,
|
|
[FromServices]IRealmService realmService,
|
|
[FromServices]KeyMapper keyMapper,
|
|
HttpContext context)
|
|
{
|
|
Realm realm = context.GetValidatedRealm();
|
|
await realmService.LoadActiveKeys(realm);
|
|
return TypedResults.Ok(keyMapper.KeyListToJsonWebKeySet(realm.Keys));
|
|
}
|
|
|
|
private static Task OpenIdConnectToken(HttpContext context)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
private static Task OpenIdConnectAuth(HttpContext context)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
private static async Task<JsonHttpResult<OpenIdConfiguration>> GetOpenIdConfiguration(
|
|
string slug,
|
|
[FromServices]IRealmService realmService,
|
|
HttpContext context)
|
|
{
|
|
Realm realm = context.GetValidatedRealm();
|
|
|
|
var s = $"{context.Request.Scheme}://{context.Request.Host}{context.Request.Path}";
|
|
var searchString = $"realms/{slug}";
|
|
int index = s.IndexOf(searchString, StringComparison.OrdinalIgnoreCase);
|
|
string baseUri = s.Substring(0, index + searchString.Length);
|
|
|
|
return TypedResults.Json(new OpenIdConfiguration()
|
|
{
|
|
AuthorizationEndpoint = baseUri + "/openid-connect/auth",
|
|
TokenEndpoint = baseUri + "/openid-connect/token",
|
|
Issuer = baseUri,
|
|
JwksUri = baseUri + "/openid-connect/jwks",
|
|
}, AppJsonSerializerContext.Default.OpenIdConfiguration);
|
|
}
|
|
|
|
private static string GetRealmInfo()
|
|
{
|
|
return "Hello World!";
|
|
|
|
/* keycloak returns this
|
|
{
|
|
"realm": "mpluskassa",
|
|
"public_key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApYbLAeOLDEwzL4tEwuE2LfisOBXoQqWA9RdP3ph6muwF1ErfhiBSIB2JETKf7F1OsiF1/qnuh4uDfn0TO8bK3lSfHTlIHWShwaJ/UegS9ylobfIYXJsz0xmJK5ToFaSYa72D/Dyln7ROxudu8+zc70sz7bUKQ0/ktWRsiu76vY6Kr9+18PgaooPmb2QP8lS8IZEv+gW5SLqoMc1DfD8lsih1sdnQ8W65cBsNnenkWc97AF9cMR6rdD2tZfLAxEHKYaohAL9EsQsLic3P2f2UaqRTAOvgqyYE5hyJROt7Pyeyi8YSy7zXD12h2mc0mrSoA+u7s/GrOLcLoLLgEnRRVwIDAQAB",
|
|
"token-service": "https://iam.kassacloud.nl/auth/realms/mpluskassa/protocol/openid-connect",
|
|
"account-service": "https://iam.kassacloud.nl/auth/realms/mpluskassa/account",
|
|
"tokens-not-before": 0
|
|
}
|
|
*/
|
|
}
|
|
} |