web-dev-qa-db-ja.com

ASP.NET(OWIN)ID:Web APIコントローラーからUserIDを取得する方法は?

(VS2013 RTW、ASP.NET MVC5を使用)

ASP.NET IDを使用する場合に、ApplicationUserクラス(およびテーブル)にプロパティを追加する方法に関する多くのドキュメントを見てきました。しかし、外部キーを介してApplicationUserテーブルにマップするコンテンツを含む個別のテーブルを作成する方法に関するドキュメントを見たことはありません。

独自のMicrosoft.AspNet.Identity.EntityFramework.IdentityDbContextを正常に導出し、独自の「UserPreferences」テーブルが、SQL Serverデータベースのさまざまな「AspNet *」テーブルと共存するようになりました。しかし、現在のユーザーのIDを取得して「UserPreferences」テーブルに新しい行を書き込むための最良の方法については明確ではありません。プロジェクトはASP.NET MVCですが、Web APIコントローラーを追加しました(そして内部で作業しています)。

実用的なソリューションがあります:

            var uman = new Microsoft.AspNet.Identity.UserManager<Microsoft.AspNet.Identity.EntityFramework.IdentityUser>(new Microsoft.AspNet.Identity.EntityFramework.UserStore<Microsoft.AspNet.Identity.EntityFramework.IdentityUser>(new App1.Data.App1DbContext()));

            var uident = User.Identity;

            var userobject = uman.FindByNameAsync(uident.Name);

            var userid = userobject.Result.Id;
            // (Perform new row creation including the userid we just looked up

(Identityフレームワークで定義されている)AspNetUsersテーブルが次のフィールドで構成されていることを考慮してください。

-id (PK, nvarchar(128) - seems to contain a GUID, not sure why not an autoincrement integer, but I assume there are reasons for this)
-Username (nvarchar(max))
-PasswordHash (nvarchar(max))
-SecurityStamp (nvarchar(max))

Idフィールド(ユーザー名ではない)がこのテーブルで参照する正しいフィールドだと思います。 (ユーザーが自分のユーザー名を変更し、他の誰かが他のユーザーのユーザー名を引き継ぐ可能性があると考えていたため、両方のフィールドが存在する可能性が高いです。) 「UserPreferences」テーブル。これは上記のコードが行うことです。しかし、このルックアップを行う必要があるのは効率が悪いようです。

重要な点は、System.Web.Mvc.Controllerのコンテキストで次のことができることです。

User.Identity.GetUserId()
(Runtime type of User.Identity: System.Security.Principal.GenericIdentity)

しかし、System.Web.Http.ApiController(Web API)のコンテキストでは、そのメソッドが存在しないため(User.Identityのランタイムタイプ:System.Security.Claims.ClaimsIdentity)できないため、代わりに依存する必要があります:

User.Identity.Name

追加のルックアップを実行して、名前をIDに変換します。これをどのように改善できるかについての提案はありますか?ユーザーデータを正しい方法で別々のテーブルに書き込むタスクに近づいていますか?

44
BenjiFB

identity 1.0 RTW package の同じ拡張メソッドにより、MVCコントローラーとWeb APIコントローラーの両方でユーザーIDを取得できるはずです。

IDパッケージの拡張機能は次のとおりです。

namespace Microsoft.AspNet.Identity
{
    public static class IdentityExtensions
    {
        public static string FindFirstValue(this ClaimsIdentity identity, string claimType);
        public static string GetUserId(this IIdentity identity);
        public static string GetUserName(this IIdentity identity);
    }
}

IIdentityは、すべてのIDタイプの基本インターフェースです。拡張メソッドを表示するには、「using Microsoft.AspNet.Identity」を追加する必要がある場合があります。

ところで、ユーザーに外部テーブルを追加することに関して、ApplicationUserを使用してUserPreferenceにナビゲーションプロパティを追加して、EFがそれらの関係を処理できるようにしないのはなぜですか?それは簡単になります。

58
Hongye Sun
_ClaimsIdentity identity = new ClaimsIdentity(OAuthDefaults.AuthenticationType);
identity.AddClaim(new Claim(ClaimTypes.Name, userName));
identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, UserID));
_

_ClaimTypes.NameIdentifier_は、関数User.Identity.GetUserId()の要求です

45
Oswaldo Alvarez

私はクレームベースアプローチを使用しています:

private ApplicationUser GetCurrentUser(ApplicationDbContext context)
{
  var identity = User.Identity as ClaimsIdentity;
  Claim identityClaim = identity.Claims.FirstOrDefault(c => c.Type == ClaimTypes.NameIdentifier);

  return context.Users.FirstOrDefault(u => u.Id == identityClaim.Value);
}
12
Mastenka

ベストアンサーの簡単な説明:

  1. _Install-Package Microsoft.AspNet.Identity.Core -Version 2.2.1_
  2. var userId = User.Identity.GetUserId();
3
neustart47

@Mastenkaの回答を試みたが、何も得られなかった。 ClaimsIdentityをチェックし、クレームタイプ「UserName」があったため、結果として、「UserName」をClaimsTypeとして使用してユーザー名を取得します。誰かがそれについてもっと情報をくれることを願っています。 「ClaimTypes.NameIdentifier」が効果を持たなかったことは奇妙に見えます。 (ApiController、ASP MVC API)

var userName = ((ClaimsIdentity)RequestContext.Principal.Identity).Claims.FirstOrDefault(cl => cl.Type == "UserName")?.Value;
0
IHAFURR