繁体   English   中英

MSTeams 选项卡 ASP.NET Core MVC 应用程序身份验证与不记名令牌未授权错误

[英]MSTeams Tab ASP.NET Core MVC App Authentication with Bearer Token Unauthorized Error

我正在尝试使用 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 Client。

因此,我尝试将本教程实施: 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 未经授权的错误。

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM