authentication - individual - web api authorization filter
¿Cómo se almacenan los tokens al portador en el lado del servidor en Web API 2? (3)
No están almacenados en el servidor: se emiten al cliente y el cliente los presenta en cada llamada. Se verifican porque están firmados por la clave de protección del host owin. En el alojamiento de SystemWeb, esa clave de protección es la configuración machineKey de web.config.
Eso es innecesario, siempre que la clave de protección que utiliza el host owin no cambie en los reinicios del servidor.
Un cliente puede retener un token mientras el token sea válido.
Estoy configurando la autenticación de token de portador en Web API 2, y no entiendo cómo (o dónde) se almacena el token de portador en el servidor. Aquí está el código relevante:
Puesta en marcha:
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;
}
}
Usando el código anterior, puedo iniciar sesión y almacenar el token del portador en el lado del cliente en una cookie, y luego hacer llamadas a los controladores marcados con [Authorize] y me deja entrar.
Mis preguntas son:
¿Dónde / cómo se almacena el token de portador en el servidor? Parece que esto está pasando por una de las llamadas de OWIN, pero no puedo decir dónde.
¿Es posible persistir los tokens de portador a una base de datos del servidor para que puedan permanecer en su lugar después de reiniciarse un servidor de API web?
Si la respuesta al n. ° 2 es no, ¿hay algún modo para que un cliente mantenga su token de portador y lo reutilice incluso después de que la API web se apague y vuelva a funcionar? Si bien esto puede ser raro en Producción, puede ocurrir con bastante frecuencia haciendo pruebas locales.
Para agregar a esto, el token puede persistir en el lado del servidor usando la propiedad SessionStore de CookieAuthenticationOptions. No recomendaría hacer esto, pero está ahí si tus tokens se vuelven excesivamente grandes.
Esta es una IAuthenticationSessionStore para que pueda implementar su propio medio de almacenamiento.
Para aquellos que están buscando cómo configurar web.config, aquí hay una muestra
<system.web>
<machineKey validation="HMACSHA256" validationKey="64-hex"
decryption="AES" decryptionKey="another-64-hex"/>
</system.web>
Necesita tanto validationKey como decriptionkey para que funcione.
Y aquí está cómo generar claves https://msdn.microsoft.com/en-us/library/ms998288.aspx