我需要配置我的.Net Core Web Api(.Net Framework)以使用ADFS 3.0(2012)来验证我们的移动客户端发送的承载令牌。
我能够从ADFS服务器生成access_token,并将其传递给Authorization标头。
我的问题在于API:如何配置它以验证和自动化用户?
我在很多地方搜索过,但我找不到明确的方法。
到目前为止我尝试了什么:
使用过IdentityServer4(因为它使用JWT而失败,而ADFS不提供OpenID 尝试使用UseOpenIdConnectAuthentication(在IdentityServer4上找到示例) 自定义中间件 我不能使用其他方法,我需要支持oAuth2。
那么,我该怎么办?
这是我最近的尝试:
var connectOptions = new OpenIdConnectOptions
{
AuthenticationScheme = "adfs",
SignInScheme = "idsrv.external", //IdentityServerConstants.ExternalCookieAuthenticationScheme,
SignOutScheme = "idsrv", //IdentityServerConstants.SignoutScheme,
AutomaticChallenge = false,
DisplayName = "ADFS",
Authority = $"https://{options.AdfsHostName}/adfs/oauth2",
ClientId = options.ClientID,
ResponseType = "id_token",
Scope = { "openid profile" },
CallbackPath = new PathString("/signin-adfs"),
SignedOutCallbackPath = new PathString("/signout-callback-adfs"),
RemoteSignOutPath = new PathString("/signout-adfs"),
ClaimsIssuer = $"https://{options.AdfsHostName}/adfs/services/trust",
//TokenValidationParameters = new TokenValidationParameters
//{
// ValidateIssuer = true,
// ValidIssuer = $"https://{options.AdfsHostName}/adfs/services/trust"
//},
};
app.UseOpenIdConnectAuthentication(connectOptions);
每次通话都会得到一个非常快的401,并带有有效的令牌。事实上,当我在控制台窗口中看到连接时,我在Roslyn控制台窗口中看不到任何有关安全验证的其他日志。
我目前正在使用ASP.Net Core 1.1.X,如果可以,我可以避免转移到.Net Core 2.0,因为我们已经在项目的后期,它包含许多重大变化......
随意询问更多信息,我将非常感谢所有好的建议!
答案 0 :(得分:2)
事实证明,我们可以将JwtBearerAuthentication与ADFS 3.0一起使用。
我最初的问题是它在/.well-known/openid-configuration处获取元数据,但ADFS 3.0不支持OpenID,这将返回404。
我在另一篇文章中读到(当我找到它时我会更新它)如果使用正确的配置,它将不需要获取配置。但是配置是什么?
我发现(MS)代码很深,如果将OpenIdConnectConfiguration对象传递给JwtBearerOptions的Configuration属性,它就不会获取元数据。
现在这是我的代码:
var rawCertData = Convert.FromBase64String(options.X509SigninCertificate);
X509Certificate2 cert = new X509Certificate2(rawCertData);
SecurityKey signingKey = new X509SecurityKey(cert);
X509证书数据来自此网址支持的adfs元数据
https://Your.ADFS.Site/FederationMetadata/2007-06/FederationMetadata.xml
它包含:
<KeyDescriptor use="signing">
<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
<X509Data>
<X509Certificate>SOMEUUENCDODEDSTRING=</X509Certificate>
</X509Data>
</KeyInfo>
</KeyDescriptor>
我只是在我的设置'X509SigninCertificate属性中复制了UUEncoded字符串。
var tokenValidationParameters = new TokenValidationParameters
{
// The signing key must match!
ValidateIssuerSigningKey = true,
IssuerSigningKey = signingKey,
// Validate the JWT Issuer (iss) claim
ValidateIssuer = true,
ValidIssuer = $"https://{options.AdfsHostName}/adfs/services/trust",
// Validate the JWT Audience (aud) claim
ValidateAudience = true,
ValidAudience = options.ClientUri, //"https://YOUR-AUDIENCE/",
// Validate the token expiry
ValidateLifetime = true,
// If you want to allow a certain amount of clock drift, set that here:
ClockSkew = TimeSpan.Zero
};
var connectOptions = new OpenIdConnectConfiguration
{
Issuer = $"https://{options.AdfsHostName}/adfs/services/trust",
};
app.UseJwtBearerAuthentication(new JwtBearerOptions
{
AutomaticAuthenticate = true,
AutomaticChallenge = true,
TokenValidationParameters = tokenValidationParameters,
Configuration = connectOptions
});
这里重要的一行是
Configuration = connectOptions
通过这样做,您告诉验证者不要获取元数据。就这么简单。
我能够验证我的令牌(AUD,ISS和SIGN),我可以在我的项目中使用ADFS。
答案 1 :(得分:1)
仅ADFS 2016支持OpenID Connect。如果要在2012年使用OAuth端点,则需要编写自己的授权处理程序。构建的示例是ASP.NET Core's own Twitter implementation。请注意,这些处理程序需要在ASP.NET Core 1. * vs 2.0 +。
中实现不同