在ADFS 4.0中使用client_credentials流将返回401

时间:2017-03-14 20:10:57

标签: oauth-2.0 adfs adal

我有"服务器应用程序访问Web API"场景。

该网站使用OIDC并验证没有问题。

但是,我有一个用例来访问一些没有用户上下文的Web API,为此,我使用client_credentials。

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

因此,假设Web API URL为:

https://my-pc/WebService/api/my-api/

Web API具有RP标识符:

https://my-pc/WebService/api/my-api/

访问控制政策是:

允许所有人

我有一条索赔规则:

c:[] =>问题(claim = c);

客户端权限设置为:

"所有客户"具有openid和user_impersonation的范围。

代码是:

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);

ADFS返回访问令牌没问题,但是当我调用web api时,我不断收到401 - 未经身份验证。

有什么想法吗?

2 个答案:

答案 0 :(得分:1)

最后想出了这个和wrote it up

这两段代码:

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

在Startup.Auth.cs

app.UseActiveDirectoryFederationServicesBearerAuthentication(
    new ActiveDirectoryFederationServicesBearerAuthenticationOptions
    {
        TokenValidationParameters = new TokenValidationParameters()
        {
            SaveSigninToken = true,
            ValidAudience = "https://my-pc/WebService"
        },

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

花了我一会儿!

答案 1 :(得分:0)

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