Как хранятся маркеры носителей на стороне сервера в 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, а затем совершать вызовы контроллеров, помеченных [Authorize], и он позволяет мне войти.

мои вопросы:

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

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

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

3 52

3 ответа:

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

  2. это не нужно, пока ключ защиты, используемый хостом owin, не изменяется при перезапуске сервера.

  3. клиент может удерживать маркер пока токен действителен.

для тех, кто ищет как настроить веб.конфиг, вот пример

<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

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

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