当前位置: 首页 > 知识库问答 >
问题:

具有自定义角色声明的Azure移动应用程序身份验证-声明消失

昌山
2023-03-14

我们有一个使用社交网络身份验证的Azure移动应用。尝试使用自定义令牌处理程序将用户角色添加为声明。

这一切都可以在localhost上运行——令牌被添加到令牌处理程序中,并且在调用AuthorizationAtinn OnAuthoration方法时可用。具有指定角色的授权属性按预期工作。

但是当运行的是Azure时——声明被添加,但当调用OnAuthorization方法时,自定义角色声明就消失了。

代码如下:

启动/配置类

public class OwinStartup
{
    public void Configuration(IAppBuilder app)
    {
        var config = GlobalConfiguration.Configuration;

        new MobileAppConfiguration()
        .AddPushNotifications()
        .ApplyTo(config);

        MobileAppSettingsDictionary settings = config.GetMobileAppSettingsProvider().
GetMobileAppSettings();

        app.UseAppServiceAuthentication(new AppServiceAuthenticationOptions()
        {
            SigningKey = ConfigurationManager.AppSettings["authSigningKey"],
            ValidAudiences = new[] { ConfigurationManager.AppSettings["authAudience"] },
            ValidIssuers = new[] { ConfigurationManager.AppSettings["authIssuer"] },
            TokenHandler = new AppServiceTokenHandlerWithCustomClaims(config)
        });

        //Authenticate stage handler in OWIN Pipeline
        app.Use((context, next) =>
        {
            return next.Invoke();
        });

        app.UseStageMarker(PipelineStage.Authenticate);

    }

添加角色声明的令牌处理程序

public class AppServiceTokenHandlerWithCustomClaims : AppServiceTokenHandler
{
    public AppServiceTokenHandlerWithCustomClaims(HttpConfiguration config)
        : base(config)
    {

    }

    public override bool TryValidateLoginToken(
        string token,
        string signingKey,
        IEnumerable<string> validAudiences,
        IEnumerable<string> validIssuers,
        out ClaimsPrincipal claimsPrincipal)
    {
        var validated = base.TryValidateLoginToken(token, signingKey, validAudiences, validIssuers, out claimsPrincipal);

        if (validated)
        {
            string sid = claimsPrincipal.FindFirst(ClaimTypes.NameIdentifier).Value;

            var roleProvider = UnityConfig.Container.Resolve<IRoleProvider>("RoleProvider");

            var roles = roleProvider.GetUserRolesBySid(sid);

            foreach (var role in roles)
            {
                ((ClaimsIdentity)claimsPrincipal.Identity).AddClaim(new Claim(ClaimTypes.Role, role));
            }
        }
        return validated;
    }
}

角色声明来自身份声明集合的角色声明示例

{http://schemas.microsoft.com/ws/2008/06/identity/claims/role: admin}
[Authorize(Roles = "admin")]

对具有Authorize属性且指定了一个或多个角色的endpoint的每次调用都失败(401)

不确定在Azure中运行时,声明是怎么回事,要么被剥离,要么没有保留在标识中。

谢谢Michael

共有2个答案

麻学博
2023-03-14

根据这篇博文,你的一些选择可能是错误的。AppSettings仅为本地调试设置,在Azure中不起作用。

试试这个:

public void Configuration(IAppBuilder app)
{
    var config = GlobalConfiguration.Configuration;

    new MobileAppConfiguration()
        .AddPushNotifications()
        .ApplyTo(config);

    MobileAppSettingsDictionary settings = config
        .GetMobileAppSettingsProvider()
        .GetMobileAppSettings();

    // Local Debugging
    if (string.IsNullOrEmpty(settings.HostName))
    {
        app.UseAppServiceAuthentication(new AppServiceAuthenticationOptions()
        {
            SigningKey = ConfigurationManager.AppSettings["authSigningKey"],
            ValidAudiences = new[] { ConfigurationManager.AppSettings["authAudience"] },
            ValidIssuers = new[] { ConfigurationManager.AppSettings["authIssuer"] },
            TokenHandler = new AppServiceTokenHandlerWithCustomClaims(config)
        });
    }
    // Azure
    else
    {
        var signingKey = GetSigningKey();
        string hostName = GetHostName(settings);

        app.UseAppServiceAuthentication(new AppServiceAuthenticationOptions
        {
            SigningKey = signingKey,
            ValidAudiences = new[] { hostName },
            ValidIssuers = new[] { hostName },
            TokenHandler = new AppServiceTokenHandlerWithCustomClaims(config)
        });
    }


    //Authenticate stage handler in OWIN Pipeline
    app.Use((context, next) =>
    {
        return next.Invoke();
    });

    app.UseStageMarker(PipelineStage.Authenticate);

}

private static string GetSigningKey()
{
    // Check for the App Service Auth environment variable WEBSITE_AUTH_SIGNING_KEY,
    // which holds the signing key on the server. If it's not there, check for a SigningKey
    // app setting, which can be used for local debugging.

    string key = Environment.GetEnvironmentVariable("WEBSITE_AUTH_SIGNING_KEY");

    if (string.IsNullOrWhiteSpace(key))
    {
        key = ConfigurationManager.AppSettings["SigningKey"];
    }

    return key;
}

private static string GetHostName(MobileAppSettingsDictionary settings)
{
    return string.Format("https://{0}/", settings.HostName);
}
雷浩思
2023-03-14

我在书中有一章是关于这个的-https://adrianhall.github.io/develop-mobile-apps-with-csharp-and-azure/chapter2/custom/#using-第三方代币

请注意关于带有附加声明的自定义身份验证的部分。您需要使用原始令牌调用自定义API,检查令牌的有效性,然后使用所需的声明生成新令牌(zumo令牌)。然后,您可以将这些声明用于任何需要的内容。

 类似资料:
  • 我使用asp.net身份与索赔主体和索赔身份。标识由自定义用户管理器创建,并作为承载令牌发送给客户端。 一切正常,但是我想指示asp.net使用角色的自定义声明类型,而不是标准的System。安全。索赔。声明类型。作用(http://schemas.microsoft.com/ws/2008/06/identity/claims/role)。 有可能吗? 编辑:我想对角色构造函数使用标准的Auth

  • 我想在我们的Web API中基于Azure AD应用程序角色进行用户授权,但这些角色不会转化为实际声明,即使我可以在令牌验证响应中看到它们。 我可以看到ClaimsMain中的角色。当前。声明列表,但在属性名称角色下,而不是声明模式下http://schemas.microsoft.com/ws/2008/06/identity/claims/role. 我已经设法通过将RoleClaimType

  • 当我将令牌粘贴到这个网站上的JWT调试器中时:https://JWT.io/,我得到了一些信息(stable_sid,sid,sub,idp,ver,iss,aud,exp,nbf),但我似乎无法得到其中的组声明。 我在Azured AD中添加了读取Microsoft graph和Azure active directory组所需的权限,但它没有改变令牌中的任何内容。 我缺少什么来获取用户组?

  • 我目前有一个使用Azure移动应用程序的后端解决方案。我已经启用了facebook、twitter、google和Microsoft登录。除此之外,我正在尝试添加一个自定义登录流。我已经设置了一个Auth0帐户和应用程序,当我在应用程序中使用auth0 lock小部件发出请求时,我能够从auth0获得令牌和配置文件。 我遵循了本指南:https://shellmonger.com/2016/04/

  • 我正在考虑将Auth0用于我的API和web应用程序,并进行查询。生成Jwt令牌时,我希望包含一些仅存在于我的用户数据库中的自定义用户声明。这是可能的,还是所有声明都需要作为Auth0中的预定义属性存在。 我有自己的用户数据库,因为我需要在那里存储一些动态和复杂的用户权限。我意识到一个选择是不将这些权限存储在令牌中,我可以有一个单独的api来获取它们,但是为了性能和简单性,我宁愿将它们包装到Jwt

  • 我有Azure AD B2C目录,并在Azure AD B2C中添加了另一个单独的Azure AD(AAD)作为身份提供商(作为开放ID连接提供商)。我可以使用链接到AAD的自定义IdP登录。 我也有身份提供者声明映射设置为用户ID到id,显示名称到名称,给定名称到given_name,姓氏到family_name和电子邮件到preferred_name(每个下面的链接)。但是当我拿回令牌并使用h