【问题标题】:MicrosoftIdentityWebApiAuthentication - Invalid Token SignatureMicrosoftIdentityWebApiAuthentication - 令牌签名无效
【发布时间】:2021-06-21 13:34:49
【问题描述】:

我的 SharePoint 加载项运行此 JavaScript 以从我的 Greeting API 获取消息:

async function getGreeting() {
    // https://www.youtube.com/watch?v=P3vkerr1nW8
    var client = new Msal.UserAgentApplication(config);
    var request = {
        scopes: ['user.read'],
        prompt: 'select_account'
    };
    let loginResponse = await client.loginPopup(request);
    let tokenResponse = await client.acquireTokenSilent(request);
    var theToken = tokenResponse.accessToken;
    // https://zinoui.com/blog/jquery-ajax-headers
    $.ajax({
        url: 'https://localhost:44316/Greeting',
        type: 'GET',
        headers: {
            'Authorization': 'Bearer ' + theToken
        },
        timeout: 600000,
        success: function (theGreeting) { alert(theGreeting); },
        error: function () { alert('Error'); }
    });
}

我的 ASP.NET Core 3.1 控制器有这个代码:

namespace SharePointTestAPI.Controllers
{
    // https://www.yogihosting.com/aspnet-core-enable-cors/
    [Authorize]
    [EnableCors("SharePointOnline")]
    [ApiController]
    [Route("[controller]")]
    public class GreetingController : ControllerBase
    {
        [HttpGet]
        public String Get()
        {
            return "Great Value Canned Salmon is Rich in Omega-3 and Vitamin D!!!";
        }
    }
}

如果我注释掉 [Authorize] 属性,则会弹出一个警告框并显示有关 Walmart Salmon 的预期消息。不幸的是,如果我把 [Authorize] 属性放回去,我会在响应头中看到这个错误:

WWW-Authenticate: Bearer error="invalid_token", error_description="签名无效"

我从 acquireTokenSilent 返回的令牌在客户端和服务器上看起来都不错。在这两种情况下,它们在 https://jwt.ms/ 处都能很好地解码,所以我不知道为什么 MicrosoftIdentityWebApiAuthentication 似乎在抱怨令牌无效。

我在 Startup.cs 中的 ConfigureServices 函数如下所示:

public void ConfigureServices(IServiceCollection services)
{
    services.AddCors(options =>
        {
            // https://docs.microsoft.com/en-us/aspnet/core/security/cors?view=aspnetcore-5.0
            // https://www.yogihosting.com/aspnet-core-enable-cors/
            options.AddPolicy(
                "SharePointOnline",
                builder =>
                {
                    builder.WithOrigins(
                        "https://myTestTenant-3b3547c0f805ae.sharepoint.com"
                    ).AllowAnyHeader().AllowAnyMethod();
                }
            );
        }
    );


    services.AddMicrosoftIdentityWebApiAuthentication(Configuration, "AzureAd");

    services.AddControllers();
}

这是我清理过的 appsettings.json:

{
/*
The following identity settings need to be configured
before the project can be successfully executed.
For more info see https://aka.ms/dotnet-template-ms-identity-platform 
*/
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "Domain": "myTenantName.onmicrosoft.com",
    "TenantId": "[someGUID]",
    "ClientId": "api://[someOtherGUID]",

    "CallbackPath": "/signin-oidc"
  },

  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
}

谁能帮我理解为什么 MicrosoftIdentityWebApiAuthentication 似乎认为我的身份验证令牌已损坏?

【问题讨论】:

  • 我遇到了类似的问题。对我来说,实际的解决方法是将范围从 ['user.read'] 更改为 [api://[myClientId]/App.Roles]

标签: c# asp.net-core asp.net-web-api msal bearer-token


【解决方案1】:

我一直收到“无效的令牌签名”错误,因为我错误地取回了访问令牌而不是 Id 令牌...我需要在我的 getGreeting 函数中更改以下行:

var theToken = tokenResponse.accessToken;

var theToken = tokenResponse.idToken.rawIdToken;

修复后,我不断收到与签名错误无关的“无效受众”错误。为了摆脱这种情况,我认为我必须通过“公开 API”部分在 Azure AD 中创建一个 appRoles 范围:

创建 appRoles 范围后,我还将 getGreeting 函数中的范围请求更改为:

scopes: ['user.read'],

scopes: ['api://[myClientId]/appRoles'],

认为这些额外的更改允许我的 SharePoint 加载项从 my API 而不是 Microsoft Graph 获取令牌。完成上述两项更改后,我的 API 会向我的 SharePoint 加载项返回预期的问候语。

我的新getGreeting函数如下所示:

async function getGreeting() {
    // https://www.youtube.com/watch?v=P3vkerr1nW8
    var client = new Msal.UserAgentApplication(config);
    var request = {
        scopes: ['api://[myClientId]/appRoles'],
        prompt: 'select_account'
    };
    let loginResponse = await client.loginPopup(request);
    let tokenResponse = await client.acquireTokenSilent(request);
    var theToken = tokenResponse.idToken.rawIdToken; 
    // https://zinoui.com/blog/jquery-ajax-headers
    $.ajax({
        url: 'https://localhost:44316/Greeting',
        type: 'GET',
        headers: {
            'Authorization': 'Bearer ' + theToken
        },
        timeout: 600000,
        success: function (theGreeting) { alert(theGreeting); },
        error: function () { alert('Error'); }
    });
}  

最后,我将 Web API 的 appsettings.json 文件中的 ClientId 更改为:

"ClientId": "api://[someOtherGUID]",

返回(不带前导 api://):

"ClientId": "[someOtherGUID]",

我最终的 appsettings.json 显示在这里:

{
/*
The following identity settings need to be configured
before the project can be successfully executed.
For more info see https://aka.ms/dotnet-template-ms-identity-platform 
*/
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "Domain": "myTenantName.onmicrosoft.com",
    "TenantId": "[someGUID]",
    "ClientId": "[someOtherGUID]",

    "CallbackPath": "/signin-oidc"
  },

  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
}

【讨论】:

    猜你喜欢
    • 2017-05-30
    • 2017-10-15
    • 2018-07-22
    • 2011-10-25
    • 2017-10-16
    • 2018-03-16
    • 1970-01-01
    • 2011-04-25
    • 2017-03-03
    相关资源
    最近更新 更多