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

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using ManagedCode.Orleans.Identity.Client.Middlewares;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.DependencyInjection;

namespace ManagedCode.Orleans.Identity.Client.Extensions;

public static class OrleansIdentityExtensions
{
public static IServiceCollection AddOrleansIdentity(this IServiceCollection services)
{
services.AddScoped<OrleansContextMiddleware>();

services.AddSignalR(options =>
{
options.AddFilter<SignalRAuthorizationFilter>();
});

return services;
}

public static IApplicationBuilder UseOrleansIdentity(this IApplicationBuilder app)
{
app.UseMiddleware<OrleansContextMiddleware>();

return app;
}
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
using System.Security.Claims;
using System.Threading.Tasks;
using ManagedCode.Orleans.Identity.Core.Extensions;
using Microsoft.AspNetCore.Http;
using Orleans.Runtime;
using ManagedCode.Orleans.Identity.Core.Constants;

namespace ManagedCode.Orleans.Identity.Client.Middlewares;

public class OrleansContextMiddleware(RequestDelegate next)
public class OrleansContextMiddleware : IMiddleware
{
public async Task InvokeAsync(HttpContext context)
public async Task InvokeAsync(HttpContext context, RequestDelegate next)
{
context.User.SetOrleansContext();
if (context.User.Identity?.IsAuthenticated == true)
{
RequestContext.Set(OrleansIdentityConstants.USER_CLAIMS, context.User);
}

await next(context);
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.SignalR;
using Orleans.Runtime;
using ManagedCode.Orleans.Identity.Core.Constants;

namespace ManagedCode.Orleans.Identity.Client.Middlewares;

public class SignalRAuthorizationFilter : IHubFilter
{
public async ValueTask<object?> InvokeMethodAsync(
HubInvocationContext invocationContext,
Func<HubInvocationContext, ValueTask<object?>> next)
{
if (invocationContext.Context.User?.Identity?.IsAuthenticated == true)
{
RequestContext.Set(OrleansIdentityConstants.USER_CLAIMS, invocationContext.Context.User);
}

return await next(invocationContext);
}

public Task OnConnectedAsync(HubLifetimeContext context, Func<HubLifetimeContext, Task> next)
{
if (context.Context.User?.Identity?.IsAuthenticated == true)
{
RequestContext.Set(OrleansIdentityConstants.USER_CLAIMS, context.Context.User);
}

return next(context);
}

public Task OnDisconnectedAsync(HubLifetimeContext context, Exception? exception, Func<HubLifetimeContext, Exception?, Task> next)
{
return next(context, exception);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ public static class OrleansIdentityConstants
public static string AUTH_TOKEN = "AUTH-TOKEN";
public static string AUTHENTICATION_TYPE = "MC-OrleansIdentity";
public const string SESSION_ID_CLAIM_NAME = "SessionId";
public const string USER_CLAIMS = "UserClaims";
}
16 changes: 16 additions & 0 deletions ManagedCode.Orleans.Identity.Core/Extensions/GrainExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using System;
using System.Security.Claims;
using Orleans;
using Orleans.Runtime;
using ManagedCode.Orleans.Identity.Core.Constants;

namespace ManagedCode.Orleans.Identity.Core.Extensions;

public static class GrainExtensions
{
public static ClaimsPrincipal GetCurrentUser(this Grain grain)
{
var requestContext = RequestContext.Get(OrleansIdentityConstants.USER_CLAIMS);
return requestContext as ClaimsPrincipal ?? new ClaimsPrincipal(new ClaimsIdentity());
}
}
27 changes: 7 additions & 20 deletions ManagedCode.Orleans.Identity.Core/Serializations/ClaimSurrogate.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,37 +4,24 @@
namespace ManagedCode.Orleans.Identity.Core.Serializations;

// This is the surrogate which will act as a stand-in for the foreign type.
// Surrogates should use plain fields instead of properties for better perfomance.
// Surrogates should use plain fields instead of properties for better performance.
[GenerateSerializer]
public struct ClaimSurrogate
public struct ClaimSurrogate(string type, string value, string valueType, string issuer, string originalIssuer)
{
public ClaimSurrogate(string type, string value, string valueType, string issuer, string originalIssuer, ClaimsIdentity? subject)
{
Issuer = issuer;
OriginalIssuer = originalIssuer;
Subject = subject;
Type = type;
Value = value;
ValueType = valueType;
}

[Id(0)]
public string Issuer { get; set; }
public string Issuer { get; set; } = issuer;

[Id(1)]
public string OriginalIssuer { get; set; }
public string OriginalIssuer { get; set; } = originalIssuer;

[Id(2)]
public ClaimsIdentity? Subject { get; set; }
public string Type { get; set; } = type;

[Id(3)]
public string Type { get; set; }
public string Value { get; set; } = value;

[Id(4)]
public string Value { get; set; }

[Id(5)]
public string ValueType { get; set; }
public string ValueType { get; set; } = valueType;
}

// This is a converter which converts between the surrogate and the foreign type.
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ public sealed class ClaimSurrogateConverter : IConverter<Claim, ClaimSurrogate>
{
public Claim ConvertFromSurrogate(in ClaimSurrogate surrogate)
{
return new Claim(surrogate.Type, surrogate.Value, surrogate.ValueType, surrogate.Issuer, surrogate.OriginalIssuer, surrogate.Subject);
return new Claim(surrogate.Type, surrogate.Value, surrogate.ValueType, surrogate.Issuer, surrogate.OriginalIssuer);
}

public ClaimSurrogate ConvertToSurrogate(in Claim value)
{
return new ClaimSurrogate(value.Type, value.Value, value.ValueType, value.Issuer, value.OriginalIssuer, value.Subject);
return new ClaimSurrogate(value.Type, value.Value, value.ValueType, value.Issuer, value.OriginalIssuer);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
namespace ManagedCode.Orleans.Identity.Core.Serializations;

// This is the surrogate which will act as a stand-in for the foreign type.
// Surrogates should use plain fields instead of properties for better perfomance.
// Surrogates should use plain fields instead of properties for better performance.
[GenerateSerializer]
public struct ClaimsIdentitySurrogate
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using System.Collections.Generic;
using System.Security.Claims;
using Orleans;

namespace ManagedCode.Orleans.Identity.Core.Serializations;

// This is the surrogate which will act as a stand-in for the foreign type.
// Surrogates should use plain fields instead of properties for better performance.
[GenerateSerializer]
public struct ClaimsPrincipalSurrogate(List<ClaimsIdentity>? identities, string? primaryIdentityType)
{
[Id(0)]
public List<ClaimsIdentity>? Identities { get; set; } = identities;

[Id(1)]
public string? PrimaryIdentityType { get; set; } = primaryIdentityType;
}
Loading
Loading