【问题标题】:Azure AD b2b "Read all users' basic profiles" permissionAzure AD b2b“读取所有用户的基本配置文件”权限
【发布时间】:2018-10-05 11:22:11
【问题描述】:

我已委派用户权限User.ReadBasic.All。在documentation 中,它声明了这一点

“允许该应用代表登录用户读取您组织中其他用户的一组基本配置文件属性。这包括显示名称、名字和姓氏、电子邮件地址、打开的扩展程序和照片。还允许应用程序来读取登录用户的完整个人资料。”

我怎样才能让所有用户都拥有基本的个人资料?

var accessToken = authContext
    .AcquireTokenAsync(graphResourceId, new ClientCredential(clientId, secret))
    .Result
    .AccessToken;

var graphserviceClient = new GraphServiceClient(
    new DelegateAuthenticationProvider(requestMessage => {
        requestMessage.Headers.Authorization = new AuthenticationHeaderValue("bearer", accessToken);
        return Task.FromResult(0);
    }));

您能否确认我的“权威”网址是否正确?

string authority = "https://login.microsoftonline.com/{tenantId}/common/oauth2/v2.0/token?&response_type=code&scope=openid%20profile%20User.Read%20User.ReadWrite%20User.ReadBasic.All";
AuthenticationContext authContext = new AuthenticationContext(authority);
var accessToken = authContext
    .AcquireTokenAsync(graphResourceId, new ClientCredential(clientId, secret))
    .Result
    .AccessToken;

【问题讨论】:

  • 权限只能是“login.microsoftonline.com{tenantId}/common”。我的意思是你想获得任何工作和学校帐户的代币。您表达的是获取令牌的完整 URI。不需要:ADAL 为您构建它(除其他外)。

标签: c# microsoft-graph-api


【解决方案1】:

您可以使用正确的 Bearer 令牌访问 Graph API users/<email_id> 端点 (https://graph.microsoft.com/v1.0/users/<email_id_of_the_user>),以获取其他用户的基本详细信息。

您也可以在 Graph Explorer 中尝试一下 - https://developer.microsoft.com/en-us/graph/graph-explorer#

【讨论】:

  • 是的——如果我在我的 c# 项目中做同样的事情,它的响应如下:“code”:“Authorization_RequestDenied”“value”:“权限不足,无法完成操作。”
  • @NimeshGami - 可能是我没有正确获得您的查询。您是否获得了正确的访问令牌?如果是,则将该令牌粘贴到 jwt.io 并检查您是否在该令牌中具有所需的范围
  • 如果令牌中缺少范围,则意味着用户尚未同意,您可能需要从 azure 门户“授予权限”。在 OAuth 2.0 的授权代码/隐式流程中,用户将有机会在登录应用程序时给予同意。但是当您使用资源所有者密码凭证流程时,您可能(不确定)想要明确授予这些权限
  • 是的,我没有在令牌中找到范围。你能帮我改正我的令牌吗?我的意思是需要做什么改变?
  • 在下面添加了解决方案 - 谢谢大家
【解决方案2】:

在这里,您实际上是从缓存中获取令牌(使用AcquireTokenSilentAsync),而当您使用调用AcquireTokenByAuthorizationCodeAsync 赎回由ASP.NET 生成的授权代码时,您的令牌实际上已添加到缓存中。您将在 ADAL.NET 概念文档中找到解释:Acquiring a token by authorization code in Web Apps

请注意,要调用图形,您可能更愿意使用 MSAL.NET。例如,参见示例的以下分支signInAndCallMicrosoftGraphaspnetcore-webapp-openidconnect-v2。这表示为一个教程,首先解释登录阶段,然后调用 API(在本例中为 Microsoft Graph)

最后,您使用的权限不适用于 Azure AD B2C(正如我在对您的问题的评论中提到的,对于 Azure AD,它应该减少到login.microsoftonline.com{tenantId}/common

【讨论】:

    【解决方案3】:

    不管你用User.ReadBasic.All还是User.Read.All都是一样的:`

    await graphServiceClient
        .Users
        .Request()
        .GetAsync();
    

    两者之间的唯一区别在于结果集。使用User.ReadBasic.All 无法访问的属性将不会在结果中返回。

    【讨论】:

    • 我正在使用相同的代码,但现在我发现问题出在访问令牌中,我没有找到使用 jwt.io 检查过的范围。你能建议我如何获得访问令牌的范围吗?
    • 您如何申请您的示波器?
    • 是的,我正在通过范围,我已经检查了范围和没有范围
    • 我问的不是if,而是如何您请求范围。
    【解决方案4】:

    我得到了解决方案并获得了我组织的用户基本资料。 解决方案:使用 AcquireTokenSilentAsync 方法获取访问令牌。 More Details

    options.Scope.Add("User.ReadBasic.All");
    
    options.ResponseType = "code id_token";                
    
    OnAuthorizationCodeReceived = async ctx =>
    {
        var request = ctx.HttpContext.Request;
        var currentUri = UriHelper.BuildAbsolute(request.Scheme, request.Host, request.PathBase, request.Path);
        var credential = new ClientCredential(ctx.Options.ClientId, ctx.Options.ClientSecret);
    
        var distributedCache = ctx.HttpContext.RequestServices.GetRequiredService<IDistributedCache>();
        string userId = ctx.Principal.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier").Value;
    
        var cache = new DistributedTokenCache(distributedCache, userId);
    
        var authContext = new AuthenticationContext(ctx.Options.Authority, cache);
    
        var result = await authContext.AcquireTokenByAuthorizationCodeAsync(
            ctx.ProtocolMessage.Code,
            new Uri(currentUri),
            credential,
            ctx.Options.Resource);
    
        ctx.HandleCodeRedemption(result.AccessToken, result.IdToken);
    }
    
    services.AddDistributedMemoryCache();
    
    
    private async Task<string> GetAccessTokenAsync()
            {
                string authority = "https://login.microsoftonline.com/{0}/common/oauth2/v2.0/token";
                string tenantId = User.FindFirst("http://schemas.microsoft.com/identity/claims/tenantid").Value;
                authority = String.Format(authority, tenantId);
                string userId = (User.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier"))?.Value;
                var cache = new DistributedTokenCache(_memoryCache, userId);
                var authContext = new AuthenticationContext(authority, cache);
                string graphResourceId = "https://graph.microsoft.com";
                string clientId = "XXX-XXX-XXX-XXX";
                string secret = "XXXX";
                var credential = new ClientCredential(clientId, secret);
                var result = await authContext.AcquireTokenSilentAsync(graphResourceId, credential, new UserIdentifier(userId, UserIdentifierType.UniqueId));
                return result.AccessToken;
            }
    

    【讨论】:

    • 这里您实际上是从缓存中获取令牌(使用 AcquireTokenSilentAsync),而当您使用调用 AcquireTokenByAuthorizationCodeAsync 兑换由 ASP.NET 生成的授权代码时,您的令牌实际上已添加到缓存中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-09
    • 1970-01-01
    • 2015-03-07
    • 2021-07-17
    相关资源
    最近更新 更多