Генерировать токен в контроллере

Я использую 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

Вы можете генерировать токен доступа внутри контроллера, вызывая 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;
    }

И вам нужно объявить вас OAuthBearerOptions как static свойство в классе Startup.cs

Но если вы хотите реализовать тихое обновление токена доступа, не требуя повторного входа в систему, вам следует рассмотреть возможность предоставления обновления токена обновления, не делайте его так, как вы предлагали. Вы можете прочитать мое подробное сообщение в блоге о том, как создавать токены обновления в SPA, построенные с помощью AngularJS.

Надеюсь, что это ответ на ваш вопрос.