2014-11-17 69 views
16

我使用Owin和ASP.NET Identity来使用OAuth令牌来保护我的Web API方法。令牌子系统设置如下:在控制器中生成令牌

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()); 

它适用于基于用户名/密码请求令牌,然后消耗这些令牌。但是,由于用户在点击呈现SPA的控制器时已经通过身份验证,我想在我的视图中生成令牌并将其传递给Javascript代码,而不必再次登录SPA。

所以我的问题是:我如何手动生成我的令牌,所以我可以将它包含在我的SPA视图中?

回答

41

你可以通过调用OAuthBearerOptions.AccessTokenFormat.Protect(ticket)产生控制器内访问令牌和代码将看起来像下面:

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

而且你需要声明你OAuthBearerOptionsstatic财产类Startup.cs

但是,如果您希望为访问令牌实施静默刷新而不要求用户再次登录,那么您应该考虑实施刷新令牌授予,不要按照您的建议进行。您可以阅读我的详细blog post,了解如何在使用AngularJS构建的SPA中生成刷新令牌。

希望这回答你的问题。

+1

在ASP.NET Web API 2中,这已经是静态的了,现在它已经从'OAuthBearerOptions'重命名为'OAuthOptions',所以现在它的'Startup.OAuthOptions.AccessTokenFormat.Protect(ticket)'。 – Fred

+1

您可以将'ExpiresUtc'属性设置为'Startup.OAuthOptions.AccessTokenExpireTimeSpan'。 – Fred

+3

如何通过控制器生成刷新令牌? –