por example ejemplo autenticacion asp.net asp.net-web-api oauth jwt access-token

asp.net - example - web api ejemplo



OAuth Calling TokenEndpointPath resulta en No se encontrĂ³ el controlador para la ruta (0)

Siguió este manual y construyó la autenticación de token. Funciona perfectamente en el modo de depuración, pero en el modo de lanzamiento una llamada al TokenEndpointPath da como resultado

El controlador para la ruta ''/ bps / oauth / token'' no se encontró o no implementa IController.

El URI tiene / bps / part debido a WebBaseUri en el archivo Web.config.

<appSettings> <add key="WebBaseUrl" value="/bps/" /> <add key="WebApiBaseUrl" value="/api/" /> <add key="owin:AutomaticAppStartup" value="true" /> <add key="LoginErrorMessage" value="Login or email is wrong" />

La clase de inicio es la siguiente:

public class Startup { public void Configuration(IAppBuilder app) { app.Use<OwinExceptionHandlerMiddleware>(); var container = new WindsorContainer().Install(new WindsorInstaller()); container.Register(Component.For<IAppBuilder>().Instance(app)); var httpDependencyResolver = new WindsorHttpDependencyResolver(container); HttpConfiguration config = new HttpConfiguration(); config.MapHttpAttributeRoutes(); config.DependencyResolver = httpDependencyResolver; app.CreatePerOwinContext(() => container.Resolve<ApplicationUserManager>()); GlobalConfiguration.Configuration.Services.Replace(typeof(IHttpControllerActivator), new WindsorControllerActivator(container)); ConfigureOAuthTokenGeneration(app, container); ConfigureOAuthTokenConsumption(app); app.UseWebApi(config); } private void ConfigureOAuthTokenGeneration(IAppBuilder app, IWindsorContainer container) { var OAuthServerOptions = new OAuthAuthorizationServerOptions { //For Dev enviroment only (on production should be AllowInsecureHttp = false) AllowInsecureHttp = true, TokenEndpointPath = new PathString("/oauth/token"), AccessTokenExpireTimeSpan = TimeSpan.FromDays(1), Provider = container.Resolve<IOAuthAuthorizationServerProvider>(), AccessTokenFormat = container.Resolve<CustomJwtFormat>(), }; app.UseOAuthAuthorizationServer(OAuthServerOptions); } private void ConfigureOAuthTokenConsumption(IAppBuilder app) { var issuer = ConfigurationManager.AppSettings["ServerAddress"]; string audienceId = ConfigurationManager.AppSettings["AudienceId"]; byte[] audienceSecret = TextEncodings.Base64Url.Decode(ConfigurationManager.AppSettings["AudienceSecret"]); // Api controllers with an [Authorize] attribute will be validated with JWT app.UseJwtBearerAuthentication( new JwtBearerAuthenticationOptions { AuthenticationMode = AuthenticationMode.Active, AllowedAudiences = new[] { audienceId }, IssuerSecurityTokenProviders = new IIssuerSecurityTokenProvider[] { new SymmetricKeyIssuerSecurityTokenProvider(issuer, audienceSecret) } }); } }

Esta es la implementación del IOAuthAuthorizationServerProvider que se está resolviendo para la propiedad Provider :

public class OAuthService : OAuthAuthorizationServerProvider { private readonly IApplicationUserService _userService; private readonly ICredentialsValidatior _credentialsValidatior; public OAuthService(IApplicationUserService userService, ICredentialsValidatior credentialsValidatior) { this._userService = userService; _credentialsValidatior = credentialsValidatior; } public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context) { context.Validated(); return Task.FromResult<object>(null); } public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context) { var allowedOrigin = context.OwinContext.Get<string>("as:clientAllowedOrigin"); if (allowedOrigin == null) allowedOrigin = "*"; context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { allowedOrigin }); /* Some user validation logick */ var user = await _userService.FindByNameAsync(context.UserName); ClaimsIdentity oAuthIdentity = await GenerateUserIdentityAsync(user); var ticket = new AuthenticationTicket(oAuthIdentity, null); context.Validated(ticket); } private async Task<ClaimsIdentity> GenerateUserIdentityAsync(ApplicationUser user) { const string authenticationType = "JWT"; var userIdentity = await _userService.CreateIdentityAsync(user, authenticationType); return userIdentity; } }

Clase que se está resolviendo para la propiedad AccessTokenFormat :

public class CustomJwtFormat : ISecureDataFormat<AuthenticationTicket> { private readonly string _issuer; public CustomJwtFormat(string issuer) { _issuer = issuer; } public string Protect(AuthenticationTicket data) { if (data == null) { throw new ArgumentNullException("data"); } string audienceId = ConfigurationManager.AppSettings["AudienceId"]; string symmetricKeyAsBase64 = ConfigurationManager.AppSettings["AudienceSecret"]; var keyByteArray = TextEncodings.Base64Url.Decode(symmetricKeyAsBase64); var signingKey = new HmacSigningCredentials(keyByteArray); var issued = data.Properties.IssuedUtc; var expires = data.Properties.ExpiresUtc; var token = new JwtSecurityToken(_issuer, audienceId, data.Identity.Claims, issued.Value.UtcDateTime, expires.Value.UtcDateTime, signingKey); var handler = new JwtSecurityTokenHandler(); var jwt = handler.WriteToken(token); return jwt; } public AuthenticationTicket Unprotect(string protectedText) { throw new NotImplementedException(); } }

Este código se ejecuta en mi máquina local y funciona bien en el modo de depuración y liberación.

El problema ocurre cuando este código se publica en el servidor de desarrollo en modo de depuración.

Descubrí que al cambiar la propiedad AllowInsecureHttp a falso en la máquina local se produce este error, pero la versión en el servidor de desarrollo es exactamente la misma. Comprobé el código IL y la propiedad AllowInsecureHttp está establecida en 1.

ACTUALIZAR

Traté de agregar / bps / part a TokenEndpointPath pero no ayudó.

Por un motivo desconocido, ahora no funciona ni siquiera localmente. Descubrí que la configuración del proyecto es tal

Traté de encontrar estas configuraciones en el servidor de desarrollo, lamentablemente, debido a la falta de mi conocimiento sobre IIS, no encontré nada.

También traté de verificar la canalización de OWIN y descubrí que la URL que se pasa a través de la canalización es la misma que está configurada en Startup.cs.

También encontré esta pregunta en StackOverflow.