Add HttpContextExtensions
Is your feature request related to a problem? Please describe.
Currently to get info about the currently logged in like user-id we have to write code like this HttpContext.ClaimAsync(ClaimTypes.NameIdentifier) can we add extensions to the HttpContext to make the code a bit easier to work with?
Describe the solution you'd like
I think adding these extensions is helpful. If this is acceptable, I can submit a PR with this. Not sure what is the best namespace for this or where in the project this would live yet.
public static class HttpContextExtensions
{
public static async Task<IUser> UserAsync(this HttpContext httpContext, UserManager<IUser>? userManager = null)
{
userManager ??= httpContext.RequestServices.GetRequiredService<UserManager<IUser>>();
return await userManager.FindByIdAsync(await httpContext.UserIdAsync());
}
public static async Task<bool> AuthorizeAsync(this HttpContext httpContext, Permission permission)
{
if (!await httpContext.IsAuthenticatedAsync())
{
return false;
}
var _authorizationService = httpContext.RequestServices.GetRequiredService<IAuthorizationService>();
return await _authorizationService.AuthorizeAsync(httpContext.User, permission);
}
public static async Task<bool> AuthorizeAsync(this HttpContext httpContext, Permission permission, object resource, IAuthorizationService? authorizationService = null)
{
if (!await httpContext.IsAuthenticatedAsync())
{
return false;
}
authorizationService ??= httpContext.RequestServices.GetRequiredService<IAuthorizationService>();
return await authorizationService.AuthorizeAsync(httpContext.User, permission, resource);
}
public static async Task<Claim> ClaimAsync(this HttpContext httpContext, string type)
{
if (!await httpContext.IsAuthenticatedAsync())
{
throw new UnauthorizedAccessException();
}
return httpContext.User.FindFirst(type);
}
public static async Task<IEnumerable<Claim>> ClaimsAsync(this HttpContext httpContext)
{
if (!await httpContext.IsAuthenticatedAsync())
{
throw new UnauthorizedAccessException();
}
return httpContext.User.Claims;
}
public static Task<bool> IsAuthenticatedAsync(this HttpContext httpContext)
{
return Task.FromResult((httpContext.User?.Identity?.IsAuthenticated) ?? false);
}
public static async Task<T> UserAsync<T>(this HttpContext httpContext)
where T : class, IUser
{
return (await httpContext.UserAsync()) as T;
}
public static async Task<string> UserIdAsync(this HttpContext httpContext)
{
var claim = await httpContext.ClaimAsync(ClaimTypes.NameIdentifier);
return (claim?.Value) ?? httpContext.User?.Identity?.Name;
}
}
If I'm not we already have some extension methods to authorize the user on specific resource
I am not a fan of adding too many methods to common objects. Either it's adding too much, or I get confused with what is standard or added by something else. Like you see httpContenxt.UserIdAsync and nothing appears when you google it. I'd rather see some kind of helpers that I invoke on purpose, like we did with the OrchardHelper.
@sebastienros thanks you. PR #12478 adds these extensions as extensions for IOrchardHelper
You can close this one.