oauth2.0 更新Microsoft Graph后找不到委托验证提供程序

eaf3rand  于 2023-03-07  发布在  其他
关注(0)|答案(2)|浏览(200)

我有下面的代码(从微软学习复制),这是工作与微软罚款.图表4.54.0

var authProvider = new DelegateAuthenticationProvider(async (request) => {
                // Use Microsoft.Identity.Client to retrieve token
                var assertion = new UserAssertion(token.AccessToken);
                var result = await clientApplication.AcquireTokenOnBehalfOf(scopes, assertion).ExecuteAsync();

                request.Headers.Authorization =
                    new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", result.AccessToken);
            });

然后我使用Microsoft.Graph5.0.0和Microsoft.Graph.Core3.0.0创建了一个新项目,这会给出一个错误,即无法找到DelegateAuthenticationProvider。
如何创建可与GraphServiceClient一起使用的AuthenticationProvider?

z2acfund

z2acfund1#

我还没有解决你的问题,因为我从来没有用过你的代码,我只是按照这个官方文件通过代表流创建GraphServiceClient。我会继续尝试。这是我已经得到的,它的工作。

using Azure.Core;
using Azure.Identity;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Primitives;
using Microsoft.Graph;

namespace WebMvcGraph5Ofo.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class HelloController : ControllerBase
    {
        public async Task<string> Get() {
            StringValues authorizationToken;
            HttpContext.Request.Headers.TryGetValue("Authorization", out authorizationToken);
            var token = authorizationToken.ToString().Replace("Bearer ","");
            var scopes = new[] { "User.Read.All" };
            var tenantId = "tenantId";
            var clientId = "client_id";
            var clientSecret = "client_secret";
            var onBehalfOfCredential = new OnBehalfOfCredential(tenantId, clientId, clientSecret, token);
            var tokenRequestContext = new TokenRequestContext(scopes);
            var token2 = onBehalfOfCredential.GetTokenAsync(tokenRequestContext, new CancellationToken()).Result.Token;
            var graphClient = new GraphServiceClient(onBehalfOfCredential, scopes);
            var user = await graphClient.Users.GetAsync();
            return "hello";
        }

        [Route("ClientCredentialFlow")]
        public async Task<string> clientAsync() {
            var scopes = new[] { "https://graph.microsoft.com/.default" };
            var tenantId = "tenantId";
            var clientId = "client_id";
            var clientSecret = "client_secret";
            var clientSecretCredential = new ClientSecretCredential(
                            tenantId, clientId, clientSecret);
            var graphClient = new GraphServiceClient(clientSecretCredential, scopes);
            var users = await graphClient.Users.GetAsync();
            return "world";
        }
        
        [Route("provider")]
        public async Task<string> providerAsync()
        {
            StringValues authorizationToken;
            HttpContext.Request.Headers.TryGetValue("Authorization", out authorizationToken);
            string incomingToken = authorizationToken.ToString().Replace("Bearer ", "");
            TokenProvider provider = new TokenProvider();
            provider.token = incomingToken;
            var authenticationProvider = new BaseBearerTokenAuthenticationProvider(provider);
            var graphServiceClient = new GraphServiceClient(authenticationProvider);
            var user = await graphServiceClient.Users.GetAsync();
            return "!!";
        }
    }
    
    public class TokenProvider : IAccessTokenProvider
    {
        public string token { get; set; }
        public AllowedHostsValidator AllowedHostsValidator => throw new NotImplementedException();

        public Task<string> GetAuthorizationTokenAsync(Uri uri, Dictionary<string, object>? additionalAuthenticationContext = null, CancellationToken cancellationToken = default)
        {
            return Task.FromResult(token);
        }
    }
}

=========================================================
就像@user2250152分享的一样,
可以通过创建IAccessTokenProvider的实现并使用Kiota抽象中的BaseBearerTokenAuthenticationProvider来完成自定义身份验证流,以代替DelegateAuthenticationProvider,如下所示
我们不能再使用DelegateAuthenticationProvider直接将其用于new GraphServiceClient(delegateAuthenticationProvider),如果我们想生成new GraphServiceClient的auth_provider,我们必须遵循使用BaseBearerTokenAuthenticationProvider + IAccessTokenProvider。我进行了如下测试,它可以工作,但似乎不符合代表流的要求。
正如您所知,O-B-O的整个流程应该是,使用访问令牌A调用受AAD保护的Web API,然后API代码使用O-B-O流程生成新的访问令牌B以执行其他请求,例如调用图形API。
那么令牌A的作用域或角色应该类似于api://xxxx/scope_name(.default for role),令牌B的作用域应该是图形API作用域,例如User.Read.All
在我的测试中,我使用了图形客户端,这样我就不需要生成令牌B,但它仍然需要对图形客户端进行身份验证。我发现当我使用api://xxxx/scope_name传递令牌A来对图形客户端进行身份验证时,我会得到错误,但当令牌A由图形API作用域生成时,我会成功地对图形客户端进行身份验证。

7lrncoxx

7lrncoxx2#

对于Microsoft.Graph v5.0.0,GraphServiceClient构造函数接受来自Azure.Identity包的TokenCredential示例。
有许多类是从令牌凭据派生的,如InteractiveBrowserCredentialClientSecretCredential
InteractiveBrowserCredential的示例

var interactiveBrowserCredential = new InteractiveBrowserCredential(interactiveBrowserCredentialOptions);
var graphServiceClient = new GraphServiceClient(interactiveBrowserCredential);

不确定,但OnBehalfOfCredential类可能与Microsoft类似。身份UserAssertion
资源:
升级到v5:认证

相关问题