OAuth调用TokenEndpointPath导致找不到路径控制器

时间:2017-01-25 14:05:12

标签: asp.net asp.net-web-api oauth jwt access-token

关注this手动和内置令牌身份验证。它在调试模式下完美运行,但在发布模式下,调用TokenEndpointPath会导致

  

找不到路径'/ bps / oauth / token'的控制器   实现IController。

由于Web.config文件中的WebBaseUri,URI具有/ bps / part。

<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" />

Startup类如下:

    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)
                }
            });
    }
}

这是为提供商属性解析的IOAuthAuthorizationServerProvider的实现:

    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;
    }
}

正在为 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();
    }
}

此代码在我的本地计算机上运行,​​并在调试和发布模式下正常工作。

将此代码以调试模式发布到开发服务器时会出现此问题。

我发现在本地计算机上将 AllowInsecureHttp 属性设置为false会导致此错误,但开发服务器上的版本完全相同。我检查了IL代码, AllowInsecureHttp 属性设置为1。

更新

我尝试将/ bps / part添加到TokenEndpointPath但它没有帮助。

由于未知原因,它现在甚至无法在本地工作。 我发现项目的设置是这样的 enter image description here

遗憾的是,我试图在开发服务器上找到这些设置,因为我对IIS缺乏了解,但我没有找到任何内容。

我还尝试检查OWIN管道,发现通过管道传递的URL与Startup.cs中配置的URL相同。

enter image description here

我还在StackOverflow上找到了this个问题。

0 个答案:

没有答案