Azure移动应用程序服务-自定义身份验证-有效访问群体

Azure移动应用程序服务-自定义身份验证-有效访问群体,azure,authentication,owin,azure-mobile-services,Azure,Authentication,Owin,Azure Mobile Services,我已经设置了Azure移动应用程序服务后端,有一个Xamarin应用程序正在使用它的服务。它在Azure移动应用程序服务中使用自定义身份验证来注册和验证应用程序的用户 对于本地开发/调试,应用程序的OWIN启动类包含一些用于设置应用程序服务的身份验证选项的代码,如中所述 在Azure中,移动应用服务的身份验证已启用(身份验证/授权),将“请求未经身份验证时要采取的操作”选项设置为“允许请求(无操作)”,以便应用程序处理请求身份验证 这一切都能按预期工作 现在,我们希望在我们的移动应用程序服务上支

我已经设置了Azure移动应用程序服务后端,有一个Xamarin应用程序正在使用它的服务。它在Azure移动应用程序服务中使用自定义身份验证来注册和验证应用程序的用户

对于本地开发/调试,应用程序的OWIN启动类包含一些用于设置应用程序服务的身份验证选项的代码,如中所述

在Azure中,移动应用服务的身份验证已启用(身份验证/授权),将“请求未经身份验证时要采取的操作”选项设置为“允许请求(无操作)”,以便应用程序处理请求身份验证

这一切都能按预期工作

现在,我们希望在我们的移动应用程序服务上支持自定义域,并支持当前的ourmobileappservice.azurewebsites.net域。我们已经配置了自定义域,配置了它的SSL证书,所有这些都运行良好。新的代币作为观众/发行者与自定义域一起发行,并且在该庄园中也进行了验证

但当以ourmobileappservice.azurewebsites.net作为受众/发行者发行代币时,在代币验证过程中会被拒绝。似乎只有我们的自定义域被允许作为有效的访问群体

对于本地开发,我们将指定
app.UseAppServiceAuthentication(新的AppServiceAuthenticationOptions{…})
,还将设置
validudiences
属性。因此,我想在Azure环境中也使用此设置,以便我们可以为令牌验证指定多个有效访问群体。注意:当然,
AppServiceAuthenticationOptions
与本地开发不同,例如SigningKey来自Azure的环境变量)

不幸的是,Azure似乎根本没有使用这个功能。它仍然以完全相同的方式不断失败。正如您所见,只有自定义域被指定为有效访问群体:

警告JWT验证失败:IDX10214:受众验证 失败。观众:''。 不匹配:validationParameters.ValidAudience: ”“或者 validationParameters.Validudiences:“null”

如何使用自定义身份验证设置配置Azure移动应用程序服务,使其有效访问群体同时支持自定义域和以前的ourmobileappservice.azurewebsites.net

编辑

为Azure指定的有效访问群体如下所示:

public static void ConfigureMobileApp(IAppBuilder app)
{
    ...

    app.UseAppServiceAuthentication(new AppServiceAuthenticationOptions
    {
        SigningKey = Environment.GetEnvironmentVariable("WEBSITE_AUTH_SIGNING_KEY"),
        ValidAudiences = new[] { "https://ourcustom.domain.com/", "https://ourmobileappservice.azurewebsites.net/" },
        ValidIssuers = new[] { "https://ourcustom.domain.com/", "https://ourmobileappservice.azurewebsites.net/" },
        TokenHandler = config.GetAppServiceTokenHandler()
    });

    ...
}

实际上,我们刚刚做了一组更新,允许您在门户中设置访问群体。如果您返回到应用程序服务验证/授权下的AAD设置,您应该会在“高级”选项卡下看到一些新选项。这包括允许的令牌访问群体的可编辑列表


如果您添加到该列表中,您就可以开始了。

您可以在自定义身份验证提供程序中使用您喜欢的任何URL对令牌进行签名。在AppServiceLoginHandler.CreateToken()方法中指定的任何内容都将进入JWT

在验证令牌时,如果您在本地调试,中间件中指定的URL列表将用于验证访问群体和颁发者。在生产环境中,Azure将神奇地使用默认Azure域和自定义域

我这样做的方式是创建一个新的web.config AppSetting,其中包含所有环境的有效签名URL

 <add key="ValidUrls" value="https://api.myproductiondomain.com/, https://myproductionapp.azurewebsites.net/, http://localhost:59475/" />
现在,在生成令牌之前的登录方法中,我检查当前请求的主机名是否在同一AppSetting白名单中。如果有效,请使用当前主机名作为我的令牌的访问群体和颁发者

像这样的东西

    // Get current URL
    var signingUrl = $"{this.Request.RequestUri.Scheme}://{this.Request.RequestUri.Authority}/";

    // Get list from AppSetting
    var validUrls = ConfigurationManager.AppSettings["ValidUrls"].Split(',').Select(u => u.Trim()).ToList();

    // Ensure current url is in whitelist
    if (!validUrls.Contains(signingUrl))
    {
        return this.Request.CreateUnauthorizedResponse();
    }


    var claims = new Claim[]
    {
        new Claim(JwtRegisteredClaimNames.Sub, user.Id),          
    };

    var signingKey = this.GetSigningKey();

    // Sign token with this
    var audience = signingUrl;
    var issuer = signingUrl; 


    // Set expirey
    var expiry = TimeSpan.FromHours(72);

    // Generate token
    JwtSecurityToken token = AppServiceLoginHandler.CreateToken(
        claims,
        signingKey,
        audience,
        issuer,
        expiry
        );

是否将“”添加到“ValidAudiences”中?是,在ValidAudiences中指定自定义域和我们的MobileAppService.azurewebsites.net。但是配置的Validudiences似乎不受尊重。你能分享你用来设置“Validudiences”的代码吗?请参阅我文章的编辑部分了解代码。谢谢,我会花点时间再回来……我们不是使用Azure Active Directory进行身份验证,而是使用自定义身份验证(管理我们自己的帐户等).所以我猜该功能不适用?@mattchenderson-允许的令牌访问群体是逗号分隔的列表、分号分隔的列表还是..?这应该是我要找的,但该功能记录在哪里??
    // Get current URL
    var signingUrl = $"{this.Request.RequestUri.Scheme}://{this.Request.RequestUri.Authority}/";

    // Get list from AppSetting
    var validUrls = ConfigurationManager.AppSettings["ValidUrls"].Split(',').Select(u => u.Trim()).ToList();

    // Ensure current url is in whitelist
    if (!validUrls.Contains(signingUrl))
    {
        return this.Request.CreateUnauthorizedResponse();
    }


    var claims = new Claim[]
    {
        new Claim(JwtRegisteredClaimNames.Sub, user.Id),          
    };

    var signingKey = this.GetSigningKey();

    // Sign token with this
    var audience = signingUrl;
    var issuer = signingUrl; 


    // Set expirey
    var expiry = TimeSpan.FromHours(72);

    // Generate token
    JwtSecurityToken token = AppServiceLoginHandler.CreateToken(
        claims,
        signingKey,
        audience,
        issuer,
        expiry
        );