Подтвердить что ты не робот

Как жетоны-носители хранятся на стороне сервера в Web API 2?

Я настраиваю аутентификацию маркера на предъявителя в Web API 2, и я не понимаю, как (или где) токен-носитель хранится на стороне сервера. Вот соответствующий код:

Startup:

public partial class Startup
{
    public static OAuthAuthorizationServerOptions OAuthOptions { get; private set; }
    public static Func<UserManager<IdentityUser>> UserManagerFactory { get; set; }
    public static string PublicClientId { get; private set; }

    static Startup()
    {
        PublicClientId = "self";
        UserManagerFactory = () => new UserManager<IdentityUser>(new UserStore<IdentityUser>());
        OAuthOptions = new OAuthAuthorizationServerOptions
        {
            TokenEndpointPath = new PathString("/Token"),
            Provider = new ApplicationOAuthProvider(PublicClientId, UserManagerFactory),
            AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
            AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
            AllowInsecureHttp = true
        };
    }

    public void ConfigureAuth(IAppBuilder app)
    {
        // Enable the application to use a cookie to store information for the signed in user
        app.UseCookieAuthentication(new CookieAuthenticationOptions());

        // Use a cookie to temporarily store information about a user logging in with a third party login provider
        app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);

        app.UseOAuthBearerTokens(OAuthOptions);
    }
}

WebApiConfig:

public class WebApiConfig
{
    public static void ConfigureWebApi()
    {
        Register(GlobalConfiguration.Configuration);
    }

    public static void Register(HttpConfiguration http)
    {
        AuthUtil.ConfigureWebApiToUseOnlyBearerTokenAuthentication(http);
        http.Routes.MapHttpRoute("ActionApi", "api/{controller}/{action}", new {action = Actions.Default});
    }
}

AuthUtil:

public class AuthUtil
{
    public static string Token(string email)
    {
        var identity = new ClaimsIdentity(Startup.OAuthOptions.AuthenticationType);
        identity.AddClaim(new Claim(ClaimTypes.Name, email));
        var ticket = new AuthenticationTicket(identity, new AuthenticationProperties());
        var currentUtc = new SystemClock().UtcNow;
        ticket.Properties.IssuedUtc = currentUtc;
        ticket.Properties.ExpiresUtc = currentUtc.Add(TimeSpan.FromMinutes(30));
        var token = Startup.OAuthOptions.AccessTokenFormat.Protect(ticket);
        return token;
    }

    public static void ConfigureWebApiToUseOnlyBearerTokenAuthentication(HttpConfiguration http)
    {
        http.SuppressDefaultHostAuthentication();
        http.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
    }
}

LoginController:

public class LoginController : ApiController
{
    ...

    public HttpResponseMessage Post([FromBody] LoginJson loginJson)
    {
        HttpResponseMessage loginResponse;
        if (/* is valid login */)
        {
            var accessToken = AuthUtil.Token(loginJson.email);
            loginResponse = /* HTTP response including accessToken */;
        }
        else
        {
            loginResponse = /* HTTP response with error */;
        }
        return loginResponse;
    }
}

Используя приведенный выше код, я могу войти и сохранить клиентский токен на стороне клиента в файле cookie, а затем сделать вызовы контроллерам, отмеченным с помощью [Авторизация], и он позволяет мне.

Мои вопросы:

  • Где/как маркер-носитель хранится на стороне сервера? Кажется, что это происходит через один из вызовов OWIN, но я не могу сказать, где.

  • Можно ли перенести токены-носители на серверную серверную базу данных, чтобы они могли оставаться на месте после перезапуска сервера веб-API?

  • Если ответ на №2 - нет, есть ли в любом случае клиент для поддержки своего токена-носителя и повторного использования его даже после того, как веб-API опустится и вернется? Хотя это может быть редко в производстве, это может часто случаться при локальном тестировании.

4b9b3361

Ответ 1

  • Они не хранятся на стороне сервера - они выдаются клиенту, а клиент представляет их при каждом вызове. Они проверены, потому что они подписаны ключом защиты хоста owin. В хосте SystemWeb этот ключ защиты - это параметр machineKey из web.config.

  • Это необязательно, если ключ защиты, используемый хостом owin, не изменяется во время перезагрузки сервера.

  • Клиент может удерживать маркер до тех пор, пока токен действителен.

Ответ 2

Для тех, кто ищет, как установить web.config, вот пример

<system.web>
<machineKey validation="HMACSHA256" validationKey="64-hex"
                 decryption="AES" decryptionKey="another-64-hex"/>
</system.web>

Для его работы требуются как validationKey, так и decriptionkey.

И вот как сгенерировать ключи https://msdn.microsoft.com/en-us/library/ms998288.aspx

Ответ 3

Чтобы добавить к этому, токен может быть сохранен на стороне сервера, используя свойство SessionStore для CookieAuthenticationOptions. Я бы не стал выступать за это, но там, если ваши жетоны становятся чрезмерно большими.

Это IAuthenticationSessionStore, чтобы вы могли реализовать свой собственный носитель.

Ответ 4

По умолчанию токен не хранится на сервере. Только ваш клиент имеет это и отправляет его через заголовок авторизации на сервер.

Если вы использовали шаблон по умолчанию, предоставленный Visual Studio, в методе Startup ConfigureAuth вызывается следующее расширение IAppBuilder: app.UseOAuthBearerTokens(OAuthOptions).