在控制器中生成令牌

时间:2014-11-17 09:49:10

标签: c# asp.net-web-api asp.net-identity

我正在使用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视图中?

1 个答案:

答案 0 :(得分:50)

您可以通过调用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;
    }

您需要在Startup.cs类中将OAuthBearerOptions声明为static属性

但是如果您希望在不请求用户再次登录的情况下实现访问令牌的静默刷新,那么您应该考虑实施刷新令牌授权,不要像您建议的那样执行。您可以阅读我详细的blog post,了解如何在使用AngularJS构建的SPA中生成刷新令牌。

希望这能回答你的问题。