2013-03-11 15 views
13

Próbuję utworzyć aplikację Windows Forms, która podłącza się do niektórych usług udostępnianych przez ASP.NET MVC WebAPI, ale mam dużo problemów z częścią uwierzytelniania/logowania.Uwierzytelnianie MVC WebAPI z Windows Forms

Nie mogę znaleźć przykładu, który po prostu pokazuje, jak to zrobić z Windows Forms, wszystko, co wydaje mi się bardzo skomplikowane i zawiera wiele bardzo głębokich kanalizacji lub wydaje się być skierowane do innych stron ASP.NET, oraz nie formularze okien.

Czy jest coś, czego mi brakuje? Czy to po prostu niemożliwe? A może po prostu nie jest to zamierzone? Spoglądam na takie rzeczy, jak .NET WebApi Authentication, które twierdzą, że to robią, ale nie widzę sposobu korzystania z plików cookie z punktu widzenia Windows Forms. Przeszedłem także http://blogs.msdn.com/b/webdev/archive/2012/08/26/asp-net-web-api-and-httpclient-samples.aspx i nadal miałem bardzo mało szczęścia.

Odpowiedz

4

Można użyć uwierzytelniania opartego na tokenach. Oto great article ilustrujący, jak można napisać niestandardowy filtr akcji, który korzysta z kryptografii publicznej/prywatnej RSA.

+1

Jestem trochę zdezorientowany. Nie mam filtrów akcji w Windows Forms. – Derek

+1

Mam na myśli uwierzytelnianie logowania, a nie szyfrowanie. – Derek

+0

Powinieneś używać filtrów akcji w swoim Web API, aby chronić swoje działania. Aplikacja WinForm będzie działała jako klient dla tych działań, jak przypuszczam. Również zaszyfrowany token może zawierać nazwę użytkownika uzyskującą dostęp do Twojej metody. Możesz więc uzyskać uwierzytelnienie, a ponieważ znasz użytkownika, nawet autoryzacja z tym podejściem. –

12

Wystarczy utworzyć token uwierzytelniania na serwerze i przechowywać go w bazie danych lub nawet w pamięci podręcznej. Następnie wyślij token z prośbami od aplikacji formularzy wygranych. WebApi powinien cały czas sprawdzać token. Jest wystarczająco dobry i masz pełną kontrolę nad procesem uwierzytelniania.

Pozwól mi podzielić się, jak to działa dla mnie:

obiektu z Autentycznymi szczegółów:

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

    public string AuthToken { get; set; } 

    public ISocialUser SocialUser { get; set; } 
} 

Web API Auth Controller:

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; 
     } 
    } 

Auth Menedżer Cache :

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; 
     } 
    } 

Auth Manager:

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 
       }; 
      } 
     } 
    } 

Globalne Filtr Działanie:

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 rejestracja:

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

Chodzi o to, że AuthCacheManager rozszerza AuthManager i dekoruje jego metody i właściwości. Jeśli nie ma nic w pamięci podręcznej, przejdź do bazy danych.

+2

Masz próbkę kodu? Darin's jest interesujący, ale możesz mieć lepszy. – hawbsl

+1

@hawbsl Zaktualizowałem swoją odpowiedź. Mam nadzieję, że znajdziesz tam coś interesującego i masz pomysł na swoją aplikację. – Andrei

+1

+50 +10 Nie wypróbowałem tego, ale wygląda na doskonałą mapę drogową, aby podążać za – hawbsl