2017-07-08 2 views
0

私はAngularJSでWeb APIを開発中です。数日前にWeb APIトークンメカニズムを実装し、アクセストークンを使用してアプリケーションにログインすることができました。私は、ASP.NET IDテーブルの代わりに外部DBテーブルを使用して、ユーザーを認証しました。複数のWEB APIコントローラでログインしてアクセスした後で、ユーザー情報を1か所に保存する方法

ユーザがログインした後、別のコントローラから簡単にアクセスできるように、ユーザ情報をクラスに保存したいと考えています。現在、ControllerクラスでClaimsIdentityを使用してユーザ情報を取得しています。

UserIdentityViewModel.cs

public class UserIdentityViewModel 
    { 
     public string UserName { get; set; } 
     public Guid UserId { get; set; } 
    } 

Startup.cs

public class Startup 
    { 
     public void Configuration(IAppBuilder app) 
     {     
      app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll); 
      var myProvider = new AuthorizationServerProvider(); 
      OAuthAuthorizationServerOptions options = new OAuthAuthorizationServerOptions 
      { 
       AllowInsecureHttp = true, 
       TokenEndpointPath = new PathString("/Token"), 
       AccessTokenExpireTimeSpan = TimeSpan.FromDays(1), 
       Provider = myProvider 
      }; 
      app.UseOAuthAuthorizationServer(options); 

      app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions()); 
     } 
    } 

AuthorizationServerProvider.cs

public class AuthorizationServerProvider : OAuthAuthorizationServerProvider 
    { 
     public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context) 
     { 
      context.Validated(); // 
     } 

     public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context) 
     {   
      string userId = context.UserName; 
      string password = context.Password; 

      EmployeeAccessBLL chkEmpAccessBLL = new EmployeeAccessBLL(); 
      EmployeeAccessViewModel vmEmployeeAccess = chkEmpAccessBLL.CheckEmployeeAccess(Convert.ToInt32(userId), password); 

      if(vmEmployeeAccess != null) 
      { 
       var identity = new ClaimsIdentity(context.Options.AuthenticationType); 
       identity.AddClaim(new Claim("username", vmEmployeeAccess.EmpName)); 
       identity.AddClaim(new Claim("userid", Convert.ToString(vmEmployeeAccess.EmployeeId))); 

       UserIdentityViewModel vmUser = new UserIdentityViewModel(); 
       vmUser.UserId = vmEmployeeAccess.EmployeeId; 
       vmUser.UserName = vmEmployeeAccess.EmpName; 

       context.Validated(identity); 
      } 
      else 
      { 
       context.SetError("invalid_grant", "Provided username and password is incorrect"); 
       return; 
      } 
     }  
    } 

EventController.cs

public class StreamEventController : ApiController 
    { 
     [Authorize] 
     [Route("api/addevent")] 
     [HttpPost] 
     public List<string> AddEvent(StreamEventViewModel vmEvent) 
     { 
      //Able to get User Information from Identity.Claims 
      var identity = (ClaimsIdentity)User.Identity; 
      string userId = identity.Claims 
          .Where(c => c.Type == "userid") 
          .Select(c => c.Value).FirstOrDefault(); 

      //Not able to get User Information from following as new object instance gets created 
      UserIdentityViewModel vmUser = new UserIdentityViewModel(); 

      vmEvent.CreatedBy = vmUser.UserId; 
      vmEvent.ModifiedBy = vmUser.UserId; 
     } 
} 

代わりに書き込み「Identity.Claims」の私は、ユーザー情報を取得するために、単純なget/setのアプローチまたは任意の他の方法論を使用したいすべてのコントローラの各メソッドで。静的クラスの使用は、ユーザーの1つの情報を保存し、複数のユーザーのログイン情報が失われるため、私の意見では悪いことです。

ログインのために他のWeb APIプロジェクトで使用されている最善の方法を教えてください。

答えて

1

あなたはこのように、コントローラのコンストラクタで設定されますプライベート変数を追加することができます。

// Should only be used in protected methods. 
private ClaimsIdentity ThisUser = null; 

public MyController() 
{ 
    if (User.Identity.IsAuthenticated) 
     ThisUser = (ClaimsIdentity)User.Identity; 
} 

[Authorize] 
[Route("api/addevent")] 
[HttpPost] 
public List<string> AddEvent(StreamEventViewModel vmEvent) 
{ 
    string userId = ThisUser.FindFirstValue("userid"); 

} 

それとも、すべてのプロパティを読み込むUserクラスを作成します。

private UserClass ThisUser = null; 

public MyController() 
{ 
    if (User.Identity.IsAuthenticated) 
     ThisUser = new UserClass(User); 
} 

[Authorize] 
[Route("api/addevent")] 
[HttpPost] 
public List<string> AddEvent(StreamEventViewModel vmEvent) 
{ 
    string userId = ThisUser.UserId; 

} 

UserClassは次のようなものです:

public class UserClass 
{ 
    public string UserId { get; private set; } 

    public UserClass(IPrincipal user) 
    { 
     UserId = user.FindFirstValue("userid"); 
    } 
} 

しかし、これは同じことの単なるオーバーヘッドです。 拡張機能に移動することが考えられます。あなたが呼び出すことができます

public static class RequestExtensions 
{ 
    public static UserClass GetUser(this HttpRequestMessage request) 
    { 
     return new UserClass(request.GetOwinContext().Authentication.User); 
    } 

    public static ClaimsIdentiy GetUser2(this HttpRequestMessage request) 
    { 
     return new (ClaimsIdentity)request.GetOwinContext().Authentication.User; 
    } 
} 

[Authorize] 
[Route("api/addevent")] 
[HttpPost] 
public List<string> AddEvent(StreamEventViewModel vmEvent) 
{ 
    string userId = Request.GetUser.UserId; 

    string userId2 = Request.GetUser2.FindFirstValue("userid"); 

} 

が、私はコードがあなたのアイデアを与えることを意味しているRequest.GetUser2.FindFirstValue("userid");

のために、私は行くだろうと思うその場合はあなたのような何かを得ます。私はコードをテストしなかったが、うまくいくはずだと思う。

+0

最高のオプションを教えてくれてありがとう。あなたが言及したように、私はエクステンションメソッドを使用して成功した結果を得ました。 – user1843970

関連する問題