C# Azure广告b2b“;读取所有用户';“基本配置文件”;许可

C# Azure广告b2b“;读取所有用户';“基本配置文件”;许可,c#,microsoft-graph-api,C#,Microsoft Graph Api,我已授予用户权限user.ReadBasic.All。在报告中,它指出了这一点 “允许应用程序代表登录用户读取组织中其他用户的基本配置文件属性集。这包括显示名称、姓名、电子邮件地址、打开的扩展名和照片。还允许应用程序读取登录用户的完整配置文件。” 如何让所有用户都具有基本配置文件 var accessToken = authContext .AcquireTokenAsync(graphResourceId, new ClientCredential(clientId, secret))

我已授予用户权限
user.ReadBasic.All
。在报告中,它指出了这一点

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

如何让所有用户都具有基本配置文件

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);
    }));
您能确认我的“权威”URL是否正确吗?

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;

您可以点击图形API
users/
endpoint(
https://graph.microsoft.com/v1.0/users/
)使用适当的承载令牌获取其他用户的基本详细信息

您也可以在图形浏览器中尝试-


无论您使用的是
User.ReadBasic.All
还是
User.Read.All
,它都是相同的:`

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

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

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

options.Scope.Add(“User.ReadBasic.All”);
options.ResponseType=“代码id\U令牌”;
OnAuthorizationCodeReceived=异步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();
字符串userId=ctx.Principal.FindFirst(“http://schemas.microsoft.com/identity/claims/objectidentifier1.价值;
var cache=新的DistributedTokenCache(distributedCache,userId);
var authContext=新的AuthenticationContext(ctx.Options.Authority,缓存);
var result=await authContext.AcquireTokenByAuthorizationCodeAsync(
ctx.ProtocolMessage.Code,
新Uri(当前Uri),
资质
ctx.选项.资源);
ctx.HandleCodeRedemption(result.AccessToken、result.IdToken);
}
AddDistributedMemoryCache();
专用异步任务GetAccessTokenAsync()
{
字符串权限=”https://login.microsoftonline.com/{0}/common/oauth2/v2.0/token”;
字符串tenantId=User.FindFirst(“http://schemas.microsoft.com/identity/claims/tenantid1.价值;
authority=String.Format(authority,tenantId);
字符串userId=(User.FindFirst(“http://schemas.microsoft.com/identity/claims/objectidentifier)价值;
var cache=newdistributedtokencache(_memoryCache,userId);
var authContext=新的AuthenticationContext(授权、缓存);
字符串graphResourceId=”https://graph.microsoft.com";
字符串clientId=“XXX-XXX-XXX-XXX”;
字符串secret=“XXXX”;
var-credential=新的ClientCredential(clientId,secret);
var result=await authContext.AcquireTokenSilentAsync(graphResourceId,credential,新用户标识符(userId,UserIdentifierType.UniqueId));
返回result.AccessToken;
}

在这里,您实际上是从缓存中获取了一个令牌(使用
AcquireTokenSilentAsync
),而当您使用调用
AcquireTokenByAuthorizationCodeAsync
兑换ASP.NET生成的授权代码时,您的令牌实际上是添加到缓存中的。您可以在ADAL.NET概念文档中找到解释:

请注意,要调用该图,您可能更希望使用MSAL.NET。例如,请参见名为的示例的以下分支:。这是一个教程,首先解释登录阶段,然后调用API(在本例中为Microsoft Graph)


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

是的-如果我在我的c#项目it响应中这样做:“code:“Authorization\u RequestDenied”“value”:“权限不足,无法完成此操作。”@NimeshGami-可能是我没有正确获取您的查询。您是否获得了正确的访问令牌?如果是,请粘贴该令牌,并检查您是否在该令牌中具有所需的作用域。如果令牌中缺少作用域,则表示用户尚未给予同意,您可能需要”从azure门户授予权限。在OAuth 2.0的授权代码/隐式流中,用户在登录应用程序时将有机会给予同意。但是,当您使用资源所有者密码凭据流时,您可能(不确定)想要明确地授予这些权限我在令牌中找不到作用域。你能帮助我如何更正我的令牌我是说需要做什么更改吗?下面添加了解决方案-谢谢所有我使用相同的代码,但现在我发现问题出在访问令牌中我找不到作用域我已使用jwt.io检查过。你能建议我如何使用jwt.io吗访问令牌中的et作用域?您如何请求您的作用域?是的,我正在传递作用域,我已使用作用域和不使用作用域进行了检查。我不是问您是否请求作用域,而是问您如何请求作用域。权限应仅为“{tenantId}/common”“。我的意思是你想为任何工作和学校帐户获得代币。您所表达的是获取令牌的完整URI。不需要:ADAL为您构建了它(除其他外)。在这里,您实际上是从缓存中获取了一个令牌(使用AcquireTokenSilentAsync),而当您使用AcquireTokenByAuthorizationCodeAsync调用赎回ASP.NET生成的授权代码时,您的令牌实际上是添加到缓存中的。
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;
        }