web-dev-qa-db-ja.com

現在認証されたユーザーのユーザー名を取得するには、ASP.NET CORE 3.0の方法は何ですか?

最新のASP.NET Core 3.0 Angularテンプレート]に取り組んでいます。知っておく必要があるのは、ActionFilterAttributeのusernameを認証される方法です。

_ClaimTypes.NameIdentifier_は現在のユーザーIDを返し、_ClaimTypes.Name_(null)usernameを返します。

これが私のコードです:

enter image description here

getUserの_d15f997a-6f65-4eb2-aecb-8b525361ae50_のUserIdがあります。

次のようにStartupクラスにIHTTPContextAccessorを登録しました。

_public IServiceProvider ConfigureServices(IServiceCollection services)
{
        services.AddDbContext<ApplicationDbContext>(options =>
            options.UseSqlServer(
                Configuration.GetConnectionString("DefaultConnection")));

        services.AddDefaultIdentity<ApplicationUser>()
            .AddEntityFrameworkStores<ApplicationDbContext>();

        services.AddIdentityServer()
            .AddApiAuthorization<ApplicationUser, ApplicationDbContext>();

        services.AddAuthentication()
            .AddIdentityServerJwt();

        //Database Setup
        services.AddDbContext<HashooDBContext>(Configuration.GetConnectionString("DefaultConnection"));

        services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();

        services.AddControllersWithViews();
        services.AddRazorPages();
        // In production, the Angular files will be served from this directory
        services.AddSpaStaticFiles(configuration =>
        {
            configuration.RootPath = "ClientApp/dist";
        });

        return ContainerSetup.InitializeWeb(Assembly.GetExecutingAssembly(), services);
}
_

Controller.cs:

_[Authorize]
[ApiController]
[Route("api/[controller]/{companycode}")]
public class DashboardTransactionsController : ControllerBase
{
    [CustomAuthorizationFilter("companycode")]
    public string Get()
    {
        return "Welcome";
    }
}
_

私は何を間違っているのか教えてください。

6
Ahmer Ali Ahsan

この問題については、IdentityServer4JwtClaimTypes.Nameをaccess_tokenに追加しなかったことが原因です。 Web Browerからaccess_tokenをチェックすると、"name": "Tom",ノードが表示されます。

回避策のために、あなたはあなた自身のITokenServiceを実装することができます

public class CustomTokenService : DefaultTokenService
{
    public CustomTokenService(IClaimsService claimsProvider
        , IReferenceTokenStore referenceTokenStore
        , ITokenCreationService creationService
        , IHttpContextAccessor contextAccessor
        , ISystemClock clock
        , IKeyMaterialService keyMaterialService
        , ILogger<DefaultTokenService> logger) 
        : base(claimsProvider, referenceTokenStore, creationService, contextAccessor, clock, keyMaterialService, logger)
    {
    }

    public override async Task<Token> CreateAccessTokenAsync(TokenCreationRequest request)
    {

        Logger.LogTrace("Creating access token");
        request.Validate();

        var claims = new List<Claim>();
        claims.AddRange(await ClaimsProvider.GetAccessTokenClaimsAsync(
            request.Subject,
            request.Resources,
            request.ValidatedRequest));

        if (request.ValidatedRequest.Client.IncludeJwtId)
        {
            claims.Add(new Claim(JwtClaimTypes.JwtId, CryptoRandom.CreateUniqueId(16)));
        }
        claims.Add(new Claim(JwtClaimTypes.Name, request.Subject.GetDisplayName()));
        var issuer = Context.HttpContext.GetIdentityServerIssuerUri();
        var token = new Token(OidcConstants.TokenTypes.AccessToken)
        {
            CreationTime = Clock.UtcNow.UtcDateTime,
            Issuer = issuer,
            Lifetime = request.ValidatedRequest.AccessTokenLifetime,
            Claims = claims.Distinct(new ClaimComparer()).ToList(),
            ClientId = request.ValidatedRequest.Client.ClientId,
            AccessTokenType = request.ValidatedRequest.AccessTokenType
        };

        foreach (var api in request.Resources.ApiResources)
        {
            if (!string.IsNullOrWhiteSpace(api.Name))
            {
                token.Audiences.Add(api.Name);
            }
        }

        return token;
    }
}

その後、ID設定の前にCustomTokenServiceを登録します

    public void ConfigureServices(IServiceCollection services)
    {
        services.TryAddTransient<ITokenService, CustomTokenService>();

        services.AddDbContext<ApplicationDbContext>(options =>
            options.UseSqlServer(
                Configuration.GetConnectionString("DefaultConnection")));

        services.AddDefaultIdentity<ApplicationUser>()
            .AddEntityFrameworkStores<ApplicationDbContext>();

        services.AddIdentityServer()
            .AddApiAuthorization<ApplicationUser, ApplicationDbContext>();

        services.AddAuthentication()
            .AddIdentityServerJwt();

    }

簡単な方法では、DefaultClaimsService.GetStandardSubjectClaimsのように上書きしようとすることができます。

public class CustomClaimsService : DefaultClaimsService
{
    public CustomClaimsService(IProfileService profile
        , ILogger<DefaultClaimsService> logger) : base(profile, logger)
    {
    }
    protected override IEnumerable<Claim> GetStandardSubjectClaims(ClaimsPrincipal subject)
    {
        var claims = base.GetStandardSubjectClaims(subject);
        var newClaims = new List<Claim>(claims)
        {
            new Claim(JwtClaimTypes.Name, subject.Identity.Name)
        };
        return newClaims;
    }
}

そして登録してください

    public void ConfigureServices(IServiceCollection services)
    {
        services.TryAddTransient<IClaimsService, CustomClaimsService>();

        //services.TryAddTransient<ITokenService, CustomTokenService>();

        services.AddDbContext<ApplicationDbContext>(options =>
            options.UseSqlServer(
                Configuration.GetConnectionString("DefaultConnection")));

        services.AddDefaultIdentity<ApplicationUser>()
            .AddEntityFrameworkStores<ApplicationDbContext>();

        services.AddIdentityServer()
            .AddApiAuthorization<ApplicationUser, ApplicationDbContext>();

        services.AddAuthentication()
            .AddIdentityServerJwt();

    }
2
Edward

IHttpContextAccessorを使用できます

private readonly IHttpContextAccessor _httpContextAccessor;

public UserService(
    IHttpContextAccessor httpContextAccessor)
{
  _httpContextAccessor = httpContextAccessor;       
}
 _

そしてあなたが使うことができるユーザー名を取得するために

_httpContextAccessor?.HttpContext?.User?.Identity?.Name;
 _

または

 _httpContextAccessor.HttpContext.User.FindFirstValue(ClaimTypes.NameIdentifier);
 _

それからあなたのスタートアップ.csに登録してください

public void ConfigureServices(IServiceCollection services)
{
    services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();
}
 _
1
Tony Ngo