example c# asp.net-web-api oauth bearer-token

example - web api c#



Tratar con tokens de portador largo desde webapi proporcionando un token sustituto (1)

No recomiendo hacer esto porque eventualmente va a almacenar los tickets de autenticación en la base de datos o en el servidor de Redis, la desventaja aquí de que con cada solicitud que contenga un token de portador, va a revisar este almacén permanente para resolver el problema. Guid y consigue de nuevo el ticket para construirlo.

Le sugiero que use JSON Web Token JWT en lugar del formato de tokens de acceso de portador predeterminado, para hacer esto necesita implementar su CustomOAuthProvider token de acceso personalizado en el Provider propiedades en OAuthAuthorizationServerOptions como el siguiente código:

OAuthAuthorizationServerOptions OAuthServerOptions = new OAuthAuthorizationServerOptions() { //For Dev enviroment only (on production should be AllowInsecureHttp = false) AllowInsecureHttp = true, TokenEndpointPath = new PathString("/oauth2/token"), AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(30), Provider = new CustomOAuthProvider(), AccessTokenFormat = new CustomJwtFormat("http://jwtauthzsrv.azurewebsites.net") };

Me he dado cuenta de que agregar más reclamos al token JWT no aumentará su tamaño dramáticamente como en el caso del formato de token de acceso predeterminado.

Debajo de una muestra de 2 JWT con diferentes reclamaciones dentro de cada una, la segunda es más grande que la primera por solo 50 caracteres. Le recomiendo que revise el contenido codificado de cada uno usando jwt.io First JWT:

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1bmlxdWVfbmFtZSI6InRhaXNlZXIiLCJzdWIiOiJ0YWlzZWVyIiwicm9sZSI6WyJNYW5hZ2VyIiwiU3VwZXJ2aXNvciJdLCJpc3MiOiJodHRwOi8vand0YXV0aHpzcnYuYXp1cmV3ZWJzaXRlcy5uZXQiLCJhdWQiOiIwOTkxNTNjMjYyNTE0OWJjOGVjYjNlODVlMDNmMDAyMiIsImV4cCI6MTQxODY0NzMyNywibmJmIjoxNDE4NjQ1NTI3fQ.vH9XPtjtAv2-6SwlyX4fKNJfm5ZTVHd_9a3bRgkA_LI

Segundo JWT (Más reclamaciones):

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1bmlxdWVfbmFtZSI6InRhaXNlZXIiLCJzdWIiOiJ0YWlzZWVyIiwicm9sZSI6WyJNYW5hZ2VyIiwiU3VwZXJ2aXNvciIsIlN1cGVydmlzb3IxIiwiU3VwZXJ2aXNvcjIiLCJTdXBlcnZpc29yMyJdLCJpc3MiOiJodHRwOi8vand0YXV0aHpzcnYuYXp1cmV3ZWJzaXRlcy5uZXQiLCJhdWQiOiIwOTkxNTNjMjYyNTE0OWJjOGVjYjNlODVlMDNmMDAyMiIsImV4cCI6MTQxODY0NzQ1NiwibmJmIjoxNDE4NjQ1NjU2fQ.TFEGDtz1RN8VmCQu7JH4Iug0B8UlWDLVrIlvc-7IK3E

El formato JWT se está convirtiendo en la forma estándar de emitir tokens de portador OAuth 2.0, y también funcionará con la concesión de token de actualización. Pero tenga en cuenta que JWT solo tiene tokens firmados y no está cifrado como el caso en el formato de token de acceso predeterminado, por lo que no almacene datos confidenciales en.

He escrito una publicación detallada en el blog en bitoftech.net sobre cómo usar tokens JWT en la API web de ASP.NET junto con una API de demostración en vivo y un código fuente en GIthub , siéntase libre de verificarlo y avisarme si necesita más ayuda.

¡Buena suerte!

Estoy creando una api web utilizando ASP.NET WebApi 2 utilizando autenticación de notificaciones, y mis usuarios pueden tener una gran cantidad de notificaciones. Con un gran número de reclamaciones, el token de portador crece muy grande rápidamente, por lo que estoy intentando encontrar una forma de devolver un token de portador mucho más corto.

Hasta ahora he descubierto que puedo proporcionar un IAuthenticationTokenProvider a la propiedad OAuthAuthorizationServerOptions.AccessTokenProvider opciones de OAuth:

OAuthOptions = new OAuthAuthorizationServerOptions { TokenEndpointPath = new PathString("/Token"), Provider = new ApplicationOAuthProvider(PublicClientId), AccessTokenExpireTimeSpan = TimeSpan.FromHours(12), AccessTokenProvider = new GuidProvider() // <-- here };

Y esto me da la oportunidad de interceptar el AuthenticationTicket y esconderlo, reemplazándolo con algo más simple, en mi ejemplo debajo de un guid hash. (Nota: en este momento, esta clase simplemente contiene un ConcurrentDictionary<string,AuthenticationTicket> con mis sesiones; en un ejemplo del mundo real, tengo la intención de almacenar las sesiones en un almacenamiento persistente)

public class GuidProvider : IAuthenticationTokenProvider { private static ConcurrentDictionary<string, AuthenticationTicket> tokens = new ConcurrentDictionary<string, AuthenticationTicket>(); public void Create(AuthenticationTokenCreateContext context) { throw new NotImplementedException(); } public async System.Threading.Tasks.Task CreateAsync(AuthenticationTokenCreateContext context) { var guid = Guid.NewGuid().ToString(); var ticket = Crypto.Hash(guid); tokens.TryAdd(ticket, context.Ticket); context.SetToken(ticket); } public void Receive(AuthenticationTokenReceiveContext context) { throw new NotImplementedException(); } public async System.Threading.Tasks.Task ReceiveAsync(AuthenticationTokenReceiveContext context) { AuthenticationTicket ticket; if (tokens.TryGetValue(context.Token, out ticket)) { if (ticket.Properties.ExpiresUtc.Value < DateTime.UtcNow) { tokens.TryRemove(context.Token, out ticket); } context.SetTicket(ticket); } } }

Así que mis preguntas:

  • ¿Es esta una forma adecuada (y segura) de proporcionar una clave sustituta en lugar de mi token generado por reclamaciones largas?
  • ¿Hay quizás un lugar mejor / más fácil donde debería estar haciendo esto dentro de la pila de webapi / OAuth?

Otra cosa a tener en cuenta es que tengo la intención de admitir tokens de actualización, y de hecho, el ejemplo anterior se extrajo de ejemplos que utilizan este tipo de mecanismo para el token de actualización, excepto que con un token de actualización parecen ser de un solo uso, por lo que ReceiveAsync Por lo general, el método siempre eliminaría el token de actualización proporcionado por el ConcurrentDictionary . No estoy del todo seguro de entender por qué.