Oauth 2.0 在ADFS 4.0中使用客户端\u凭据流将返回401

Oauth 2.0 在ADFS 4.0中使用客户端\u凭据流将返回401,oauth-2.0,adfs,adal,Oauth 2.0,Adfs,Adal,我有“服务器应用程序访问web API”的场景 该网站使用OIDC,身份验证没有问题 然而,我有一个在没有用户上下文的情况下访问某些web API的用例,为此,我使用客户机凭据 服务器应用程序具有客户端ID和密钥 因此,假设web API URL为: web API具有RP标识符: 访问控制策略为: 允许所有人 我有一条索赔规则: c:[]=>问题(索赔=c) 客户端权限设置为: 具有openid和用户模拟范围的“所有客户端” 代码是: AuthenticationContext ac =

我有“服务器应用程序访问web API”的场景

该网站使用OIDC,身份验证没有问题

然而,我有一个在没有用户上下文的情况下访问某些web API的用例,为此,我使用客户机凭据

服务器应用程序具有客户端ID和密钥

因此,假设web API URL为:

web API具有RP标识符:

访问控制策略为:

允许所有人

我有一条索赔规则:

c:[]=>问题(索赔=c)

客户端权限设置为:

具有openid和用户模拟范围的“所有客户端”

代码是:

AuthenticationContext ac = new AuthenticationContext("https://my-adfs/adfs/", false);
// ClientCredential contains client_id and secret key 
AuthenticationResult result = await ac.AcquireTokenAsync("https://my-pc/WebService/api/my-api/", clientCredential);

HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, "https://my-pc/WebService/api/my-api/");
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", result.AccessToken);

HttpContent content = new FormUrlEncodedContent(new[] { new KeyValuePair<string, string>("foo", "blah"), new KeyValuePair<string, string>("foo1", "blah1") });
request.Content = content;
HttpResponseMessage response = await client.SendAsync(request);
AuthenticationContext ac=新的AuthenticationContext(“https://my-adfs/adfs/“,假);
//ClientCredential包含客户端id和密钥
AuthenticationResult=等待ac.AcquireTokenAsync(“https://my-pc/WebService/api/my-api/“,客户端凭据);
HttpRequestMessage请求=新建HttpRequestMessage(HttpMethod.Post)https://my-pc/WebService/api/my-api/");
request.Headers.Authorization=新的AuthenticationHeaderValue(“承载者”,result.AccessToken);
HttpContent content=newformurlencodedcontent(new[]{newkeyvaluepair(“foo”,“blah”),newkeyvaluepair(“foo1”,“blah1”)});
request.Content=内容;
HttpResponseMessage response=等待客户端.SendAsync(请求);
ADFS返回访问令牌没有问题,但是当我调用web api时,我总是得到一个401-Unauthenticated


有什么想法吗?

由于您在访问令牌中没有获得用户主体,因此您没有附加到主体的用户会话。当Web API在cookie中查找主体(如果您发送访问令牌,则为授权标头)时,它找不到主体,您仍然是匿名用户

终于找到了答案

两段代码:

using Microsoft.IdentityModel.Clients.ActiveDirectory;

ClientCredential clientCredential = new ClientCredential(clientId, secretKey);

AuthenticationContext ac = new AuthenticationContext("https://my-adfs/adfs/", false);
AuthenticationResult result = await ac.AcquireTokenAsync("https://my-pc/WebService", 

clientCredential);

HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post,  

"https://my-pc/WebService/api/my-api/");
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", result.AccessToken);

HttpContent content = new FormUrlEncodedContent(new[] { new KeyValuePair<string,  

string>("foo", "blah"), new KeyValuePair<string, string>("foo1", "blah1") });
request.Content = content;
HttpResponseMessage response = await client.SendAsync(request);

if (response.IsSuccessStatusCode)
    // etc

花了我一段时间

什么用户主体?没有用户。正确!但是,从Web API的角度来看,服务器应用程序就是用户,对吗?当您向api发送访问令牌时,它使用解析器对JWT进行解码并读取主体。由于令牌没有用户主体,它只返回401。我认为这取决于您如何与web api通信。我们目前正在应用程序中使用auth_代码流。在我的例子中,客户机在对用户进行身份验证后获得一个访问令牌,我们解析它以获取声明并加载安全上下文。我们创建一个新的JWT(具有主体),并将其传递给用户试图访问的资源。此资源解码JWT并识别用户。现在,我们正在尝试实现客户机\u凭证流,因为我们没有从访问令牌获取主体,资源无法从JWT识别用户。
app.UseActiveDirectoryFederationServicesBearerAuthentication(
    new ActiveDirectoryFederationServicesBearerAuthenticationOptions
    {
        TokenValidationParameters = new TokenValidationParameters()
        {
            SaveSigninToken = true,
            ValidAudience = "https://my-pc/WebService"
        },

        MetadataEndpoint = "https://my-adfs/FederationMetadata/2007-06/FederationMetadata.xml"
});