web-dev-qa-db-ja.com

Asp.NET Core 2.0 APIコントローラではUser.Identity.Nameが空です

ASP.NETコア自体は初めてです。ただし、ASP.NET Core 2.0でWebAPIを作成しています。 JWT Bearer Tokenベースの認証を構成しました。以下は、トークンを返すコントローラーです。

    [AllowAnonymous]
[Route("api/[controller]")]
public class TokenController : Controller
{
    private readonly UserManager<UserEntity> userManager;
    private readonly SignInManager<UserEntity> signInManager;

    public TokenController(UserManager<UserEntity> userManager, SignInManager<UserEntity> signInManager)
    {
        this.userManager = userManager;
        this.signInManager = signInManager;
    }

    // GET: api/values
    [HttpGet]
    public async Task<IActionResult> Get(string username, string password, string grant_type)
    {
        {
            var user = await userManager.FindByEmailAsync(username);

            if (user != null)
            {
                var result =await signInManager.CheckPasswordSignInAsync(user, password, false);
                if (result.Succeeded)
                {

                    var claims = new[]
                    {
                        new Claim( JwtRegisteredClaimNames.Sub, username),
                        new Claim( JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
                        new Claim( JwtRegisteredClaimNames.GivenName, "SomeUserID")
                    };

                    var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("secretesecretesecretesecretesecretesecrete"));
                    var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

                    var token = new JwtSecurityToken( issuer: "test",
                                                     audience: "test",
                                                     claims: claims,
                                                      expires: DateTime.Now.AddDays(15),
                                                      signingCredentials: creds);

                    return Ok(new { access_token = new JwtSecurityTokenHandler().WriteToken(token), expires_on=DateTime.Now.AddDays(15) });

                }
            }
        }

        return BadRequest("Could not create token");
    }


}

ただし、[Authorize]属性で装飾されたValuesController APIを呼び出す場合。 ser.Identity.Nameが空です。ユーザーに関する情報が得られません。よくわかりませんが、トークンコントローラは正しく記述されています。私のValuesControllerを保護している限り、それは正しいと思います。ただし、何か不足している可能性があります。助けてください。

注:Macコミュニティを追加したVisual Studio 2017を使用して開発しています

10
Nps

はい、user.identity.nameに翻訳される一意の名前のクレームを指定する必要があります。

new Claim(JwtRegisteredClaimNames.UniqueName, user.UserName)
22

ASP.Net Core 2でもこの問題が発生しており、この問題の別の原因を誰も発見していないことに本当に驚いています。

WebアプリケーションがIISに展開されると、「User.Identity.Name "は常にnullを返します。IISサイトでは匿名アクセスが無効になっており、Windows認証が有効になっています。

だが。

私のASP.Net Core 2に "launchSettings.json "ファイルはPropertiesフォルダーの下に静かに隠されており、そこにはいくつかのiisSettingsもあり、ここでは" windowsAuthentication "が不思議なことにデフォルトでfalseに設定されていました。

enter image description here

windowsAuthentication」をtrueに、「anonymousAuthentication」をfalseに変更すると、問題が解決しました。

これを行った後、「User.Identity.Name "には最終的に正しいユーザー名が含まれていました。

しかし、この設定は一体何ですか?なぜthisが、IIS Managerで設定した実際の設定よりも優先されるのですか?!

9
Mike Gledhill

「DefaultIdentity」(個々のユーザーアカウント)を使用してこの問題(Core 3.1)も発生しました。 User.Identity.Nameがnull、User.Identity.IsAuthenticated = true。 httpContextAccessorを使用すると、userIdを取得でき、そのIDでユーザーとUserNameを見つけることができます。コントローラに追加

using System.Security.Claims;
...
private readonly IHttpContextAccessor _httpContextAccessor;
public MyController(MyContext context, IHttpContextAccessor httpContextAccessor)
{
  _context = context;
  _httpContextAccessor = httpContextAccessor;
}

// Any method username needed
[HttpGet("{id}")]
public async Task<ActionResult<MyInfo>> GetMyInfo(int id)
{
  var userId = _httpContextAccessor.HttpContext.User.FindFirst(ClaimTypes.NameIdentifier).Value;
  var user = _context.AspNetUsers.Find(userId);
  var userName = user.UserName;
  ...
}

Startup.csに次の行を追加します。

services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
0
Gerard