2013-03-11 30 views
13

ASP.NET MVC WebAPIによって公開されているいくつかのサービスにプラグインするWindowsフォームアプリケーションを作成しようとしていますが、認証/ログインの部分で大きな問題があります。WindowsフォームからのMVC WebAPI認証

私は、Windowsフォームからこれを行う方法を実証するだけの例は見つからないと思います。私が見つけたものは非常に畳み込まれていて、非常に深い配管を含んでいるか、他のASP.NET Webサイトをターゲットにしているようです。ウィンドウズフォームではありません。

紛失しているものがありますか?これはちょうど不可能ですか?それとも、意図していないのですか?私はこれを行うと主張している.NET WebApi Authenticationのようなものを見てきましたが、Windows Formsの観点からクッキーを使用する方法はわかりません。私はまたhttp://blogs.msdn.com/b/webdev/archive/2012/08/26/asp-net-web-api-and-httpclient-samples.aspxに行って、まだほとんど運がなかった。

答えて

4

トークンベースの認証を使用できます。ここにはgreat articleがあり、RSAパブリック/プライベート暗号を使用するカスタムアクションフィルタを書く方法を説明しています。

+1

私は少し混乱しています。私はWindowsフォームでアクションフィルターを持っていません。 – Derek

+1

私は本当に暗号化ではなく、ログイン認証を参照しています。 – Derek

+0

アクションを保護するには、Web APIでアクションフィルターを使用する必要があります。 WinFormsアプリケーションは、私が想定しているアクションのクライアントとして機能します。また、暗号化されたトークンには、あなたのメソッドにアクセスするユーザー名が含まれている可能だから、あなたは認証を得ることができ、あなたはこの方法での承認さえも、ユーザーを知っているからです。 –

12

サーバー側で認証トークンを作成し、データベースまたはキャッシュに保存するだけです。次に、あなたのwinフォームアプリケーションからのリクエストでこのトークンを送信します。 WebApiは常にこのトークンをチェックする必要があります。それだけで十分で、あなたの認証プロセスを完全に制御できます。

それは私のためにどのように動作するか、私は共有しましょう:認証の詳細を

オブジェクト:

public class TokenIdentity 
{ 
    public int UserID { get; set; } 

    public string AuthToken { get; set; } 

    public ISocialUser SocialUser { get; set; } 
} 

ウェブAPI認証コントローラ:

public class AuthController : ApiController 
    { 
     public TokenIdentity Post(
      SocialNetwork socialNetwork, 
      string socialUserID, 
      [FromUri]string socialAuthToken, 
      [FromUri]string deviceRegistrationID = null, 
      [FromUri]DeviceType? deviceType = null) 
     { 
      var socialManager = new SocialManager(); 

      var user = socialManager.GetSocialUser(socialNetwork, socialUserID, socialAuthToken); 

      var tokenIdentity = new AuthCacheManager() 
       .Authenticate(
        user, 
        deviceType, 
        deviceRegistrationID); 

      return tokenIdentity; 
     } 
    } 

認証キャッシュマネージャ:

public class AuthCacheManager : AuthManager 
    { 
     public override TokenIdentity CurrentUser 
     { 
      get 
      { 
       var authToken = HttpContext.Current.Request.Headers["AuthToken"]; 
       if (authToken == null) return null; 

       if (HttpRuntime.Cache[authToken] != null) 
       { 
        return (TokenIdentity) HttpRuntime.Cache.Get(authToken); 
       } 

       return base.CurrentUser; 
      } 
     } 

     public int? CurrentUserID 
     { 
      get 
      { 
       if (CurrentUser != null) 
       { 
        return CurrentUser.UserID; 
       } 
       return null; 
      } 
     } 

     public override TokenIdentity Authenticate(
      ISocialUser socialUser, 
      DeviceType? deviceType = null, 
      string deviceRegistrationID = null) 
     { 
      if (socialUser == null) throw new ArgumentNullException("socialUser"); 
      var identity = base.Authenticate(socialUser, deviceType, deviceRegistrationID); 

      HttpRuntime.Cache.Add(
       identity.AuthToken, 
       identity, 
       null, 
       DateTime.Now.AddDays(7), 
       Cache.NoSlidingExpiration, 
       CacheItemPriority.Default, 
       null); 

      return identity; 
     } 
    } 

認証マネージャ:

public abstract class AuthManager 
    { 
     public virtual TokenIdentity CurrentUser 
     { 
      get 
      { 
       var authToken = HttpContext.Current.Request.Headers["AuthToken"]; 
       if (authToken == null) return null; 

       using (var usersRepo = new UsersRepository()) 
       { 
        var user = usersRepo.GetUserByToken(authToken); 

        if (user == null) return null; 

        return new TokenIdentity 
        { 
         AuthToken = user.AuthToken, 
         SocialUser = user, 
         UserID = user.ID 
        }; 
       } 
      } 
     } 

     public virtual TokenIdentity Authenticate(
      ISocialUser socialUser, 
      DeviceType? deviceType = null, 
      string deviceRegistrationID = null) 
     { 
      using (var usersRepo = new UsersRepository()) 
      { 
       var user = usersRepo.GetUserBySocialID(socialUser.SocialUserID, socialUser.SocialNetwork); 

       user = (user ?? new User()).CopyFrom(socialUser); 

       user.AuthToken = System.Guid.NewGuid().ToString(); 

       if (user.ID == default(int)) 
       { 
        usersRepo.Add(user); 
       } 

       usersRepo.SaveChanges(); 

       return new TokenIdentity 
       { 
        AuthToken = user.AuthToken, 
        SocialUser = user, 
        UserID = user.ID 
       }; 
      } 
     } 
    } 

グローバルアクションフィルタ:

public class TokenAuthenticationAttribute : System.Web.Http.Filters.ActionFilterAttribute 
{ 
    public override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext actionContext) 
    { 
     if (actionContext.Request.RequestUri.AbsolutePath.Contains("api/auth")) 
     { 
      return; 
     } 

     var authManager = new AuthCacheManager(); 

     var user = authManager.CurrentUser; 

     if (user == null) 
     { 
      throw new HttpResponseException(HttpStatusCode.Unauthorized); 
     } 

     //Updates the authentication 
     authManager.Authenticate(user.SocialUser); 
    } 
} 

Global.asaxの登録:

GlobalConfiguration.Configuration.Filters.Add(new AuthFilterAttribute()); 

AuthCacheManagerはAuthManagerを拡張し、そのメソッドとプロパティを装飾するという考え方があります。キャッシュ内に何もない場合は、データベースをチェックしてください。

+2

コードサンプルがありますか?ダーリンは面白いですが、あなたはより良いものを持っているかもしれません。 – hawbsl

+1

@hawbsl私は自分の答えを更新しました。興味深いものを見つけてあなたのアプリケーションのアイデアを得ることを願っています。 – Andrei

+1

+50 +10私はそれを試していませんが、それは従うべき優れたロードマップのように見えます – hawbsl

関連する問題