0

この投稿は長くなる可能性がありますが、回答に必要なすべての詳細が必要になります。ログイン時にHttpContextユーザーにクレームを追加する方法

HttpContextユーザーにクレームを追加するための適切な方法論のために、必要に応じてRazorを使用してこれらのクレームを検索できるように、多くのユーザーが検索しました。例えば

、デフォルトAsp.Netコア2.0 Webアプリケーションで

、_LoginPartialは、ユーザーの電子メールを表示するコードを持っています。私は、ユーザーのフルネームにそれを変更したい場合は、私は上の請求を追加したいと思う

// Add profile data for application users by adding properties to the ApplicationUser class 
public class ApplicationUser : IdentityUser 
{ 
    public string FirstName { get; set; } 

    public string LastName { get; set; } 

    public DateTime DateOfBirth { get; set; } 

    public Gender Gender { get; set; } 
    ...balance of code removed for brevity 
} 

(これは、登録プロセスがApplicationUserクラスを適切に変更して、最初と最後の名のエントリを含んで想定しています)デフォルトのアプリで現在使用されているUserManagerメソッドの代わりに、フルネームと性別を使用するユーザー。 (そして、他の道)

現在のデフォルトのWEPアプリコード

私は達成するために期待しています何
@if (SignInManager.IsSignedIn(User)) 
{ 
    <form asp-area="" asp-controller="Account" asp-action="Logout" method="post" id="logoutForm" class="navbar-right"> 
     <ul class="nav navbar-nav navbar-right"> 
      <li> 
       <a asp-area="" asp-controller="Manage" asp-action="Index" title="Manage">Hello @UserManager.GetUserName(User)!</a> 
      </li> 
      <li> 
       <button type="submit" class="btn btn-link navbar-btn navbar-link">Log out</button> 
      </li> 
     </ul> 
    </form> 
} 
else 
{ 
...code removed for brevity 
} 

。この

<a asp-area="" asp-controller="Manage" asp-action="Index" title="Manage">Hello @((ClaimsIdentity) User.Identity).GetSpecificClaim("avatarUrl")!</a>  

注でこれを置き換える 、

<a asp-area="" asp-controller="Manage" asp-action="Index" title="Manage">Hello @UserManager.GetUserName(User)!</a> 

は:GetSpecificClaimは、請求項を取得する拡張メソッドです。

私は、クレームを追加する最も良い場所はログインメソッドにあると信じています。

  1. クレームはちょうど設定したのに、なぜクレームリストが空である:

    public async Task<IActionResult> Login(LoginViewModel model, string returnUrl = null) 
        { 
         ViewData["ReturnUrl"] = returnUrl; 
         if (!ModelState.IsValid) return View(model); 
         // Now model is valid, require the user to have a confirmed email before they can log on. 
         var user = await _userManager.FindByEmailAsync(model.Email); 
         if (user != null) 
         { 
          if (!await _userManager.IsEmailConfirmedAsync(user)) 
          { 
           ModelState.AddModelError(string.Empty, 
            "You must have a confirmed email to log in."); 
           return View(model); 
          } 
         } 
         else 
         { 
          ModelState.AddModelError(string.Empty, 
           "There is no registered account for the email address supplied."); 
          return View(model); 
         } 
    
         var result = await _signInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, lockoutOnFailure: true); 
         if (result.Succeeded) 
         { 
          _logger.LogInformation("User logged in."); 
    
          // Add claims to signed in user 
          var userClaims = HttpContext.User.Claims.ToList(); 
          userClaims.Add(new Claim("fullname", user.GetFullName(user.UserName))); 
          userClaims.Add(new Claim("avatarUrl", user.AvatarUrl)); 
    
          // Using ClaimsTransformer 
          // Add claims here for the logged in user using AddUserInfoClaimsAsync extension method 
          **var ct = new ClaimsHelpers.ClaimsTransformer(); 
          var identityWithInfoClaims = await ct.AddUserInfoClaimsAsync(User, user);** 
    
          return RedirectToLocal(returnUrl); 
         } 
         if (result.RequiresTwoFactor) 
         { 
          return RedirectToAction(nameof(LoginWith2Fa), new { returnUrl, model.RememberMe }); 
         } 
         if (result.IsLockedOut) 
         { 
          _logger.LogWarning("User account locked out."); 
          return RedirectToAction(nameof(Lockout)); 
         } 
    
         ModelState.AddModelError(string.Empty, "Invalid login attempt."); 
         return View(model); 
        } 
    

    しかしuserClaims変数は常に

    Breakpoint showing empty claim list

    質問空か?

  2. 身分証明書には別の種類の申し立てがありますか?
  3. これを行うより良い方法はありますか?

UPDATE:私はいくつかの初期の試みで一緒にClaimsTransformerを入れていた 、私は得ることができます主張はそれが(ログインコントローラコードの太字で上記の変更を参照)を使用しますが、私は今と何をしますか追加しましたClaimsPrincipal変数identityWithinfoClaims? Userは読み込み専用なので、私はそれに等しいと設定することはできませんので、追加されたクレームを持つオブジェクトは適切に使用されますか?

答えて

0

カスタムクレームを追加または変換するには、カスタムClaimsAuthenticationManagerを実装して使用します。 How To: Transform Incoming Claims。ここ

public class ClaimsTransformationModule : ClaimsAuthenticationManager { 
    public override ClaimsPrincipal Authenticate(string resourceName, ClaimsPrincipal incomingPrincipal) { 
     if (incomingPrincipal != null && incomingPrincipal.Identity.IsAuthenticated == true) { 
      var identity = (ClaimsIdentity)incomingPrincipal.Identity; 
      var user = GetUserData(identity); 

      identity.AddClaim(new Claim("fullname", user.GetFullName(user.UserName))); 
      identity.AddClaim(new Claim("avatarUrl", user.AvatarUrl)); 
     } 

     return incomingPrincipal; 
    } 
} 

GetUserData()はユーザ名を指定し、DBからユーザエンティティを検索します。

登録web.configで、この変圧器:

<system.identityModel> 
    <identityConfiguration> 
     <claimsAuthenticationManager type="MyProject.ClaimsTransformationModule , MyProject, Version=1.0.0.0, Culture=neutral" /> 
    </identityConfiguration> 
</system.identityModel> 
+0

...投稿に記載されているように、.netコア2を使用しています。コアにウェブ設定はありません。 GetUserDataがHttpContext.Userプリンシパルに渡されていますか? – dinotom

+0

申し訳ありませんが、asp.netコアを使用していることを確認していません。この場合、クレーム変換を設定する方法を説明するブログがあります。[ASP.NET Core 2.0に注意:クレーム変換は複数回実行される可能性があります](https://brockallen.com/2017/08/30/beware-in -asp-net-core-2-0-claims-transformation-may-run-multiple-times /)を使用します。 –

+0

'GetUserData'は、ユーザプリンシプルから' IIdentity identity 'を取得します。ユーザー名は 'identity.Name'でアクセス可能でなければなりません。 –

0

は、我々はいくつかの時間前に正確に同じ問題が発生しました。 解決策はかなり簡単です。 IUserClaimsPrincipalFactoryインターフェイスの独自の実装を作成し、DIコンテナに登録するだけで済みます。もちろん、そのインターフェイスの実装を一から書く必要はありません。クラスをUserClaimsPrincipalFactoryから派生させ、1つのメソッドをオーバーライドできます。

ここにはコードスニペットを含むstep-by-step descriptionがあります。

関連する問題