Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Signalr 信号器Azure令牌的Web Api不工作_Signalr_Asp.net Web Api2_Owin_Azure Active Directory - Fatal编程技术网

Signalr 信号器Azure令牌的Web Api不工作

Signalr 信号器Azure令牌的Web Api不工作,signalr,asp.net-web-api2,owin,azure-active-directory,Signalr,Asp.net Web Api2,Owin,Azure Active Directory,我有一个Asp.NETWebAPI(Api1),需要将消息发送到SignalrRealtimeAPI(Api2)。我正在尝试使用Azure广告承载令牌进行身份验证。Api1的客户端是一个JavaScript客户端,它使用ADAL.js从Azure获取令牌 var authContext = new AuthenticationContext({ tenant: tenantId, clientId: jsclientId,

我有一个Asp.NETWebAPI(Api1),需要将消息发送到SignalrRealtimeAPI(Api2)。我正在尝试使用Azure广告承载令牌进行身份验证。Api1的客户端是一个JavaScript客户端,它使用ADAL.js从Azure获取令牌

    var authContext = new AuthenticationContext({    
            tenant: tenantId,
            clientId: jsclientId,
            postLogoutRedirectUri: window.location.origin,
            cacheLocation: 'localStorage',
            endpoints: {
                api1Url: api1ResourceUri
            }
    });

    authContext.acquireToken(jsclientId, function (error, token) {
        if (error || !token) {
            authContext.clearCache();
            authContext.login();
        } 
    });
JS客户端在授权头中将此令牌附加到对Api1的所有Api调用。在Api1中,我使用以下代码从Azure AD获取访问令牌

var userAssertion = new UserAssertion(bootstrapContext.Token, "urn:ietf:params:oauth:grant-type:jwt-bearer", userName);

var result = await authenticationContext.AcquireTokenAsync(api2ResourceId,  new ClientCredential(api1clientId, api1clientSecret), userAssertion);
我将此访问令牌作为授权头“承载令牌值”附加到请求中。在Signalr Hub Owin启动类中,我有以下代码

app.UseWindowsAzureActiveDirectoryBearerAuthentication(
new WindowsAzureActiveDirectoryBearerAuthenticationOptions
{
    TokenValidationParameters = new TokenValidationParameters
    {
            ValidAudiences = api1Audiences,
            SaveSigninToken = true
    },
    Tenant = configSection.TenantId
});

虽然集线器上的ClaimSideEntity显示为已验证,但未设置用户的身份。identity.name为空。看起来用户身份没有传递到信号器集线器

API中没有用户标识,因为您是作为应用程序而不是用户对其进行身份验证

acquireTokenAsync重载仅接收资源和ClientCredentials,用于客户端凭据流(也称为仅应用程序流)

您需要做的是使用代表流将您为API1获得的令牌交换为API2的令牌

因此,在API1的Startup.Auth、TokenValidation参数中,将Save SigninToken设置为true,如下所示:

app.UseOpenIdConnectAuthentication(
  OpenIdConnectAuthenticationOptions
  {
      // ...
      TokenValidationParameters = new TokenValidationParameters
      {
        SaveSigninToken = true
      },
      // ...
  });
然后,无论您想在哪里调用API2,请执行以下操作:

ClientCredential clientCred = new ClientCredential(clientId, appKey);
var bootstrapContext = ClaimsPrincipal.Current.Identities.First().BootstrapContext as System.IdentityModel.Tokens.BootstrapContext;
string userName = ClaimsPrincipal.Current.FindFirst(ClaimTypes.Upn) != null ? ClaimsPrincipal.Current.FindFirst(ClaimTypes.Upn).Value : ClaimsPrincipal.Current.FindFirst(ClaimTypes.Email).Value;
string userAccessToken = bootstrapContext.Token;
UserAssertion userAssertion = new UserAssertion(bootstrapContext.Token, "urn:ietf:params:oauth:grant-type:jwt-bearer", userName);

result = await authContext.AcquireTokenAsync(api2ResourceId, clientCred, userAssertion);
请参见示例:,具体是ToDoService的Startup.Auth.cs和TodoListController.cs

注意:此示例适用于本机应用程序+web api,您正在将其改编为web应用程序+web api

编辑-通过在JS acquireToken调用中指定API1,确保JS代码正在为API1请求令牌,如下所示:

var authContext = new AuthenticationContext({    
        tenant: tenantId,
        clientId: jsclientId,
        postLogoutRedirectUri: window.location.origin,
        cacheLocation: 'localStorage',
        endpoints: {
            api1Url: api1ResourceUri
        }
});

authContext.acquireToken(api1clientId, function (error, token) {
    if (error || !token) {
        authContext.clearCache();
        authContext.login();
    } 
});

我的错,应该是api2ResourceId,修复了它。我更新了AcquireTokenAsync和UserAssertion,如前所述。现在我得到一个错误“断言受众声明与所需值不匹配”。它说预期的受众是Api1的受众,但受众是调用Api1的javascript客户机的受众。我已经更新了问题以显示JS客户端代码。您在AcquireContext调用中仍然缺少UserAssertion。很抱歉,我没有完全更新问题。我正在AcqureToken调用中传递userAssertion。听起来您有3个Azure AD应用程序。一个用于JS客户端,一个用于API 1,一个用于API 2。您能否更新您的问题,以便所有资源和客户端标识它们属于哪个应用程序?i、 e.客户顾问、资源顾问等。。。