2014-11-17 13 views
16

Używam tożsamości Owin i ASP.NET do korzystania z tokenów OAuth do zabezpieczania moich metod Web API. Token podsystem jest skonfigurowany jako takie:Generowanie tokena w kontrolerze

var oauthOptions = new OAuthAuthorizationServerOptions() 
{ 
    TokenEndpointPath = new PathString("/Token"), 
    Provider = new SimpleAuthorizationServerProvider(), 
    AccessTokenFormat = new TicketDataFormat(app.CreateDataProtector(typeof(OAuthAuthorizationServerMiddleware).Namespace, "Access_Token", "v1")), 
    RefreshTokenFormat = new TicketDataFormat(app.CreateDataProtector(typeof(OAuthAuthorizationServerMiddleware).Namespace, "Refresh_Token", "v1")), 
    AccessTokenProvider = new AuthenticationTokenProvider(), 
    RefreshTokenProvider = new AuthenticationTokenProvider(), 
    AccessTokenExpireTimeSpan = TimeSpan.FromDays(14), 
    AllowInsecureHttp = true 
}; 

app.UseOAuthAuthorizationServer(oauthOptions); 
app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions()); 

Działa świetnie na żądania tokenów w oparciu o nazwę użytkownika/hasło, a następnie spożywanie tych tokenów. Jednakże, ponieważ użytkownik jest już uwierzytelniony po trafieniu kontrolera, który renderuje SPA, chciałbym wygenerować token w moim widoku i przekazać go do kodu Javascript, zamiast konieczności ponownego logowania w SPA.

Moje pytanie brzmi: w jaki sposób mogę ręcznie wygenerować mój token, aby można go było uwzględnić w widoku SPA?

Odpowiedz

41

Można wygenerować token dostępu wewnątrz kontrolera poprzez wywołanie OAuthBearerOptions.AccessTokenFormat.Protect(ticket) a kod będzie wyglądać jak poniżej:

 private JObject GenerateLocalAccessTokenResponse(string userName) 
    { 

     var tokenExpiration = TimeSpan.FromDays(1); 

     ClaimsIdentity identity = new ClaimsIdentity(OAuthDefaults.AuthenticationType); 

     identity.AddClaim(new Claim(ClaimTypes.Name, userName)); 

     var props = new AuthenticationProperties() 
     { 
      IssuedUtc = DateTime.UtcNow, 
      ExpiresUtc = DateTime.UtcNow.Add(tokenExpiration), 
     }; 

     var ticket = new AuthenticationTicket(identity, props); 

     var accessToken = Startup.OAuthBearerOptions.AccessTokenFormat.Protect(ticket); 

     JObject tokenResponse = new JObject(
            new JProperty("userName", userName), 
            new JProperty("access_token", accessToken), 
            new JProperty("token_type", "bearer"), 
            new JProperty("expires_in", tokenExpiration.TotalSeconds.ToString()), 
            new JProperty(".issued", ticket.Properties.IssuedUtc.ToString()), 
            new JProperty(".expires", ticket.Properties.ExpiresUtc.ToString()) 
    ); 

     return tokenResponse; 
    } 

i trzeba zadeklarować Ci OAuthBearerOptions jako static właściwość w klasie Startup.cs

Ale jeśli chcesz wdrożyć ciche odświeżanie dla tokenu dostępu, nie żądając od użytkownika ponownego logowania, powinieneś rozważyć wdrożenie odświeżania tokena, nie rób tak, jak sugerowałeś. Możesz przeczytać mój szczegółowy blog post o tym, jak wygenerować odświeżające tokeny w SPA zbudowanym z AngularJS.

Mam nadzieję, że to odpowiada na twoje pytanie.

+1

W ASP.NET Web API 2 jest to już statyczne, a jego nazwa została zmieniona z 'OAuthBearerOptions' na' OAuthOptions', więc teraz jest to 'Startup.OAuthOptions.AccessTokenFormat.Protect (ticket)'. – Fred

+1

Możesz ustawić właściwość 'ExpiresUtc' na' Startup.OAuthOptions.AccessTokenExpireTimeSpan'. – Fred

+3

Jak wygenerować token odświeżania za pomocą kontrolera? –