如何为单个工具实现 OAuth2,而不将其用作我的应用程序的授权解决方案

How to implement OAuth2 for a single tool, without using it as my application's authorization solution

我目前在 .NET Core 中有一个 MVC 站点,由 public API 支持。我的用户必须登录(没有 [Anonymous] 控制器),并且已经使用 DotNetCore.Authentication 提供程序成功完成身份验证。一切都很好。

我现在(根据用户请求)尝试做的是实现用户在我站点内的页面上阅读和查看他们的 Outlook 365 日历的功能。表面上看起来并不太难......我所要做的就是让他们通过 microsoftonline 使用我注册的应用程序进行身份验证,然后 - 一旦他们给予批准 - 重定向回我的应用程序以查看他们的日历事件我现在可以拉(可能使用 Graph)。

原则上这似乎非常简单明了。我的困惑来自于无法为单个控制器而不是整个站点实施身份验证。我可以在网上找到的所有 OAuth2(或 OpenID,或 OWIN,或任何你喜欢的风格)示例——其中有无数个——都想使用授权来控制整个站点的 User.Identity。我不想更改我的站点范围的身份验证协议;我不想向 Startup.cs 添加任何内容;我不希望任何东西超出一个控制器的范围。

tldr;有没有办法只调用 https://login.microsoftonline.com/common/oauth2/v2.0/authorize(或 facebook,或 google,或其他),并取回我可以在网站的那个区域为该用户使用的代码或令牌,而不是它是否接管了网站其余部分已经存在的身份验证?

对于正在寻找此答案的任何其他人,我已经弄清楚(经过多次试验和错误)如何在短时间内对单个用户进行身份验证,而无需使用对整个应用程序进行身份验证的中间件。

    public async Task<IActionResult> OfficeRedirectMethod()
    {
        Uri loginRedirectUri = new Uri(Url.Action(nameof(OfficeAuthorize), "MyApp", null, Request.Scheme));
        var azureADAuthority = @"https://login.microsoftonline.com/common";

        // Generate the parameterized URL for Azure login.
        var authContext = GetProviderContext();
        Uri authUri = await authContext.GetAuthorizationRequestUrlAsync(_scopes, loginRedirectUri.ToString(), null, null, null, azureADAuthority);

        // Redirect the browser to the login page, then come back to the Authorize method below.
        return Redirect(authUri.ToString());
    }

    public async Task<IActionResult> OfficeAuthorize()
    {
        var code = Request.Query["code"].ToString();

        try
        {
            // Trade the code for a token.
            var authContext = GetProviderContext();
            var authResult = await authContext.AcquireTokenByAuthorizationCodeAsync(code, _scopes);

            // do whatever with the authResult, here
        }
        catch (Exception ex)
        {
            System.Diagnostics.Trace.WriteLine(ex.ToString());
        }

        return View();
    }

    public ConfidentialClientApplication GetContext()
    {
        var clientId = "OfficeClientId;
        var clientSecret = "OfficeClientSecret";
        var loginRedirectUri = new Uri(@"MyRedirectUri");
        TokenCache tokenCache = new MSALSessionCache().GetMsalCacheInstance();

        return new ConfidentialClientApplication(
            clientId,
            loginRedirectUri.ToString(),
            new ClientCredential(clientSecret),
            tokenCache,
            null);
    }

我不知道这是否对除我以外的任何人都有帮助;我只知道这是一个似乎不是通过快速搜索就能轻易解决的问题。