2016-08-16 59 views
7

wszystkimASP.NET Identity 2.0 uwierzytelnienia przeciwko naszym własnym okaziciela serwerze

Mam Server Security, które jedynym celem jest zapewnienie żetony na okaziciela z jednego punktu końcowego: http://example.com/token

przykładu żądanie:

POST http://example.com/token HTTP/1.1 
User-Agent: Fiddler 
Content-Type: x-www-form-urlencoded 
Host: example.com 
Content-Length: 73 

grant_type=password&[email protected]&password=examplePassword 

Przykład reakcji:

HTTP/1.1 200 OK 
Cache-Control: no-cache 
Pragma: no-cache 
Content-Type: application/json;charset=UTF-8 
Expires: -1 
Server: Microsoft-IIS/10.0 
X-Powered-By: ASP.NET 
Date: Tue, 16 Aug 2016 12:04:39 GMT 
{ 
    "access_token": "xxxx", 
    "token_type": "bearer", 
    "expires_in": 17999, 
    "refresh_token": "xxxx", 
    ".issued": "Tue, 16 Aug 2016 12:04:38 GMT", 
    ".expires": "Tue, 16 Aug 2016 17:04:38 GMT" 
} 

we hav Jest to aplikacja kątowa, która używa tego punktu końcowego do uwierzytelniania i robi to dobrze.

Co staramy się osiągnąć bez większego sukcesu, to stworzyć aplikację MVC, która używa tego samego serwera do uwierzytelnienia, chcielibyśmy, aby kod znalazł się na wierzchu Identity 2.0, jeśli to możliwe.

W naszej AccountController (przykład projektu) mamy Login(LoginModel model) metodę, która obsługuje logowanie i wygląda tak (tak samo jak szablon przykładowy projekt):

var result = await _signInManager.PasswordSignInAsync(model.UserName, model.Password, model.RememberMe, shouldLockout: false); 

Dysponujemy własnym przeróbka IUserStore, UserManager, SignInManager.

ja uważane nadrzędnym

public Task<SignInStatus> PasswordSignInAsync(string userName, string password, bool isPersistent, bool shouldLockout) on `SignInManager<,>` and make a web call across to the security server. 

Domyślna implementacja PasswordSignInAsync połączeń UserManager.FindByNameAsync jednak oznaczałoby to, że będę musiał narazić metodę przeglądową na moim serwerze bezpieczeństwa, aby potwierdzić nazwę użytkownika, który istnieje naprawdę nie robi brzmi dobrze.

Muszę coś pomijać i wiem, że nie byłoby to tak skomplikowane, nasza aplikacja MVC musi wykorzystywać uwierzytelnianie plików cookie, ale także utrzymywać token niedźwiedzia dla kolejnych połączeń z naszym drugim serwerem zasobów.

(Doceniam, że mogę tu mieszać technologie, stąd pytanie).

Ta funkcja działa również na OWIN.

+0

Chcesz, aby nowa aplikacja MVC korzystała z istniejącego serwera uwierzytelniania dla tokena? Jeśli tak, to jaką korzyść masz nadzieję zyskać? –

+0

Twoja aplikacja MVC nie musi mieć kontrolera logowania. Ani taki, który i tak zabiera użytkownika i hasło. Twoja aplikacja MVC powinna uwierzytelnić i uzyskać AccessToken ze swojego SecurityServera, i należy odszyfrować ten token w MVC. Będzie to możliwe, jeśli serwer ma pewne właściwości. Przeczytaj ten artykuł, aby uzyskać więcej informacji: http://bitoftech.net/2014/09/24/decouple-owin-authorization-server-resource-server-oauth-2-0-web-api/ – Xavero

+0

Nie jestem pewien, czy poprawne pytanie: * To, co staramy się osiągnąć bez większego sukcesu, to stworzyć aplikację MVC, która używa tego samego serwera do uwierzytelnienia * - Nie można trafić tego punktu końcowego tokenu serwera bezpieczeństwa przez HttpClient z akcji logowania AccountController przy użyciu nazwy użytkownika i hasło, które spowoduje ustawienie tokena w pliku cookie odpowiedzi, jeśli żądanie zostanie uwierzytelnione? – Developer

Odpowiedz

2

W tym przypadku nie sądzę, że powinieneś używać Identity 2.0 w swojej aplikacji MVC. należy utworzyć AuthenticationClient aby połączyć się z serwerem uwierzytelniania, można również korzystać z tej biblioteki, aby zbudować taki klientowi https://www.nuget.org/packages/Thinktecture.IdentityModel.Client/

public class AuthenticationClient { 
    public ClaimsIdentity GetClaimsIdentity(string username, string password) { 
     //Call your authentication server to get your token and also claims associated with your identity. 
     //You can look at an example code how to do it: https://github.com/IdentityServer/IdentityServer3.Samples/blob/master/source/Clients/ConsoleResourceOwnerClient/Program.cs 
     //and create a ClaimsIdentity object out of those information 

     var identity = GetIdentity(); 

     //The key point here is to add AccessToken and RefreshToken as custom claims to your identity so you retrieve these tokens back on subsequent requests. 
     identity.AddClaim(new Claim("access_token", accessToken)); 
     identity.AddClaim(new Claim("refresh_token", refreshToken)); 
    } 
} 

ten spełni Twoje wymagania:

uwierzytelniania Wykorzystanie plików cookie, ale także utrzymać niedźwiedzia token dla kolejnych wywołań do naszego innego serwera zasobów.

Twój Login metoda na AccountController powinno być tak:

public ActionResult Login(LoginModel model) 
{ 
    var identity = authenticationClient.GetClaimsIdentity(model.UserName, model.Password); 

    if (identity == null) { 
     return new HttpUnauthorizedResult(); 
    } 
    //Sign in the user 
    var ctx = Request.GetOwinContext(); 
    var authenticationManager = ctx.Authentication; 
    authenticationManager.SignIn(identity); 

    return new HttpStatusCodeResult(HttpStatusCode.OK); 
} 

Zakładam, że masz już zarejestrować tę middleware do korzystania z uwierzytelniania cookie:

public void ConfigureAuth(IAppBuilder app) 
{ 
    app.UseCookieAuthentication(new CookieAuthenticationOptions 
    { 
     AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie, 
     LoginPath = new PathString("/Account/Login") 
    }); 
} 

Teraz dla wszystkich kolejnych żądań, ty może odzyskać token dostępu, aby wywołać serwer zasobów z Twojego ClaimsIdentity:

User.Identity.Claims.FirstOrDefault(x => x.Type == "access_token");