Closed vanillajonathan closed 2 years ago
I'll be honest this is way beyond the scope of what identity is aimed at. This sort of thing we leave to Identity Server, OpenIddict and the various cloud platform identity services.
IdentityServer is an implementation of OpenID Connect — an unwieldy beast designed by a consortium of behemoths to cover every imaginable enterprise scenario which makes it difficult to understand, configure and setup.
IdentityServer is great as the stand-alone-hosted identity management centerpiece of an enterprise as it supports:
But it is not suitable as a smaller piece of just one application. Example an SPA or an application that provides an API alongside Razor pages with Identity.
Rolling our own PAT implementation would be just as unwieldy, complicated and prone to error, locking people into a custom protocol and client. That's not suitable for anything modern at all.
Perhaps it could be a simple implementation with just one GeneratePersonalAccessTokenAsync
method that returns a token as a string in JWT format. The method would accept a DateTimeUtc
or a TimeSpan
that would be used to set the exp
claim. Furthermore it would add claims from the AspNetUserClaims
table. The token would be compatible with the existing AddJwtBearer
middleware. No custom protocol, no custom client.
You could do that today, with your own custom code. But PATs are specialized requirements anyway, not suitable for inclusion in a general starting point framework. Identity is for web based logins, anything after that we leave to the community. If there's something blocking the implementation of a community feature we'd look at how to unblock it, but that's very different to implementing it ourselves.
True, it would look something like this.
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using Microsoft.IdentityModel.Tokens;
namespace Microsoft.AspNetCore.Identity;
public static class UserManagerExtensions
{
/// <summary>
/// Generates a personal access token for the specified <paramref name="userName"/>.
/// </summary>
/// <param name="userName">The user to generate a personal access token for.</param>
/// <param name="scopes">The scopes which the token provides access to.</param>
/// <param name="tokenDescriptor">The information which used to create a token.</param>
/// <returns>The <see cref="Task"/> that represents the asynchronous operation,
/// containing a personal access token for the specified <paramref name="userName"/>.</returns>
public static async Task<string> GeneratePersonalAccessTokenAsync<TUser>(this UserManager<TUser> userManager, string userName, IEnumerable<string> scopes, SecurityTokenDescriptor tokenDescriptor)
where TUser : class
{
var user = await userManager.FindByNameAsync(userName);
var claims = await userManager.GetClaimsAsync(user);
tokenDescriptor.Subject.AddClaims(claims);
if (scopes.Any())
{
var scopeString = string.Join(", ", scopes.Select(x => x));
tokenDescriptor.Subject.AddClaim(new Claim("scope", scopeString));
}
var tokenHandler = new JwtSecurityTokenHandler();
var token = tokenHandler.CreateJwtSecurityToken(tokenDescriptor);
var encoded = tokenHandler.WriteToken(token);
return encoded;
}
}
The user would have to pass in a SecurityTokenDescriptor
.
Another alternative would be opaque tokens persisted to a database table.
public class PersonalAccessToken
{
public Guid Id { get; set; }
public Guid UserId { get; set; }
public string Scope { get; set; }
public DateTimeOffset ExpiresAt { get; set; }
}
Thank you for contacting us. Due to a lack of activity on this discussion issue we're closing it in an effort to keep our backlog clean. If you believe there is a concern related to the ASP.NET Core framework, which hasn't been addressed yet, please file a new issue.
This issue will be locked after 30 more days of inactivity. If you still wish to discuss this subject after then, please create a new issue!
Background and Motivation
Users on a website powered by ASP.NET Core Identity could also want to delegate access to third-party applications to interact with an API on the website using personal access tokens.
Proposed API
Usage Examples
Alternative Designs
Risks
Is your feature request related to a problem? Please describe the problem.
Users can only interact with the application through a web browser. Users can not interact with the application through other applications.
Describe the solution you'd like
For ASP.NET Core Identity to provide a way to generate personal access tokens for users.