【问题标题】:MSTeams Tab ASP.NET Core MVC App Authentication with Bearer Token Unauthorized ErrorMSTeams Tab ASP.NET Core MVC App Authentication with Bearer Token Unauthorized Error
【发布时间】:2021-06-24 21:13:32
【问题描述】:

我正在尝试使用 ASP.NET Core Web App MVC 制作 MS Teams 选项卡应用程序。该应用需要图形客户端来访问 SharePoint 资源。

我已经成功实现了微软的这个例子:https://github.com/OfficeDev/Microsoft-Teams-Samples/tree/main/samples/tab-sso/csharp

因此应正确配置应用注册。

但是通过上述教程的身份验证,我无法在“ConfigureServices”方法中注入 Microsoft Graph 客户端。

因此,我尝试将本教程:https://docs.microsoft.com/en-us/graph/tutorials/teams?tutorial-step=4 实现为 MVC 应用程序。但是现在当我尝试获取具有授权的方法时,我不断收到 401 错误。

在配置方法中,“app.UseAuthentication()”也在“app.UseAuthorization()”之前

这是我的“ConfigureServices”方法

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllersWithViews();
        services.AddMicrosoftIdentityWebApiAuthentication(Configuration)
            .EnableTokenAcquisitionToCallDownstreamApi()
            .AddMicrosoftGraph(Configuration.GetSection("Graph"))
            .AddInMemoryTokenCaches();
    }

这是我在 index.cshtml 中的 JS

    (function () {
        if (microsoftTeams) {
            microsoftTeams.initialize();

            microsoftTeams.authentication.getAuthToken({
                successCallback: (token) => {
                    $('<code/>', {
                        text: token,
                        style: 'word-break: break-all;'
                    }).appendTo('#tab-container');
                    fetch('/GetTest', {
                        method: 'get',
                        headers: {
                            "Content-Type": "application/text",
                            "Authorization": "Bearer " + token
                        }
                    }).then(response => {
                        response.text()
                            .then(body => {
                                $('#tab-container').empty();
                                $('<code/>', {
                                    text: body
                                }).appendTo('#tab-container');
                            });
                    }).catch(error => {
                        console.error(error);
                        renderError(error);
                    });
                },
                failureCallback: (error) => {
                    renderError(error);
                }
            });
        }
    })();

这是我调用的“GetTest”方法

    [Authorize]
    [HttpGet("GetTest")]
    public async Task<string> GetTest()
    {
        // This verifies that the access_as_user scope is
        // present in the bearer token, throws if not
        HttpContext.VerifyUserHasAnyAcceptedScope(apiScopes);

        // To verify that the identity libraries have authenticated
        // based on the token, log the user's name
        _logger.LogInformation($"Authenticated user: {User.GetDisplayName()}");

        try
        {
            // TEMPORARY
            // Get a Graph token via OBO flow
            var token = await _tokenAcquisition
                .GetAccessTokenForUserAsync(new[]{
                    "User.Read",
                    "Sites.ReadWrite.All" });

            // Log the token
            _logger.LogInformation($"Access token for Graph: {token}");
            return "{ \"status\": \"OK\" }";
        }
        catch (MicrosoftIdentityWebChallengeUserException ex)
        {
            _logger.LogError(ex, "Consent required");
            // This exception indicates consent is required.
            // Return a 403 with "consent_required" in the body
            // to signal to the tab it needs to prompt for consent
            HttpContext.Response.ContentType = "text/plain";
            HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
            await HttpContext.Response.WriteAsync("consent_required");
            return null;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error occurred");
            return null;
        }
    }

在应用程序的这种状态下,该方法现在应该返回需要同意的 403 错误,但我只收到 401 Unauthorized 错误。

我不确定是否可以使用与教程中相同的授权,因为我的项目是 MVC 项目。

【问题讨论】:

    标签: c# asp.net-core-mvc microsoft-graph-api microsoft-teams


    【解决方案1】:

    我不是该主题的专家,但我认为您正在尝试将两种不同且不兼容的方法结合在一起。你不需要执行第二个教程中的步骤,因为 Teams SSO 已经为你提供了执行基本 Graph 访问所需的内容。重要的是,Teams SSO 为您提供的令牌不能直接用于 Graph,它需要交换为“代表”(OBO)令牌,该令牌可用作 Graph 调用的 Bearer 令牌。

    在“SSOAuthHelper”的GetAccessTokenOnBehalfUserAsync 方法中,您链接的示例有代码可以为您执行此操作。如果您想查看它的实际效果,请查看“HomeController”中的GetUserAccessToken 方法。而不是像 GetUserAccessToken 方法那样仅仅返回它,您实际上可以在控制器方法中使用它。例如,参见this sample 中的GetUserData

    【讨论】:

    • @davbue - 希尔顿提供的帮助能否解决您的问题?
    • 不幸的是没有,但我发现即使使用 Microsoft Graph 教程的确切解决方案:docs.microsoft.com/en-us/graph/tutorials/teams 我也会收到 401 错误。也许这个问题与环境有关。无论如何,我很可能会继续联系 Microsoft 支持。
    猜你喜欢
    • 2020-08-15
    • 2015-07-11
    • 2017-04-24
    • 2019-06-21
    • 2019-03-24
    • 2017-02-07
    • 2021-02-06
    • 2021-08-29
    • 2019-10-18
    相关资源
    最近更新 更多