使用ADFS 2012进行.net Core Api身份验证

时间:2017-11-30 02:47:31

标签: asp.net-core oauth-2.0 adfs3.0

我需要配置我的.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,因为我们已经在项目的后期,它包含许多重大变化......

随意询问更多信息,我将非常感谢所有好的建议!

2 个答案:

答案 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 +。

中实现不同