asp.net-mvc - 如何在 ASP.NET MVC 中实现单点登录 (ADFS)

标签 asp.net-mvc single-sign-on adfs ws-federation

仅供引用:请参阅 2019 年 2 月 12 日更新

我创建了一个 ASP.NET MVC 应用程序(使用 Visual Studio)并试图让它使用 Active Directory 联合服务器来处理 SSO。请注意,这不是使用 Azure。

所以,第一步有效 - 我导航到我的登录页面,并且有一个按钮允许我登录另一个服务 [“Federation”]。这将启动我输入凭据的 ADFS 网页,但在返回我的网站时,我收到以下错误:

IDX10214: Audience validation failed. Audiences: '[PII is hidden]'. Did not match: validationParameters.ValidAudience: '[PII is hidden]' or validationParameters.ValidAudiences: '[PII is hidden]'.

Exception Details: Microsoft.IdentityModel.Tokens.SecurityTokenInvalidAudienceException: IDX10214: Audience validation failed. Audiences: '[PII is hidden]'. Did not match: validationParameters.ValidAudience: '[PII is hidden]' or validationParameters.ValidAudiences: '[PII is hidden]'.

显然,我的设置不正确......所以需要知道我错过了什么......

这是我的(删减的)代码:

Startup.Auth.cs

public partial class Startup
{
    public void ConfigureAuth(IAppBuilder app)
    {
        // Configure the db context, user manager and signin manager to use a single instance per request
        app.CreatePerOwinContext(ApplicationDbContext.Create);
        app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
        app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);    

        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationType = WsFederationAuthenticationDefaults.AuthenticationType
        });

        app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);

        ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(ValidateServerCertificate);

        app.UseWsFederationAuthentication(new WsFederationAuthenticationOptions
        {
            MetadataAddress = "https://adfs.Mydomain.com/FederationMetadata/2007-06/FederationMetadata.xml",
            Wtrealm = "https://myWebServer/myWebApplication"
        });
    }

    private bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslpolicyerrors)
    {
        return true; // Our "TEST" ADFS has a fake certficate, so we don't want to validate it.
    }
}

Web.Config 中的部分

  <appSettings>
    <add key="webpages:Version" value="3.0.0.0" />
    <add key="webpages:Enabled" value="false" />
    <add key="ClientValidationEnabled" value="true" />
    <add key="UnobtrusiveJavaScriptEnabled" value="true" />

    <add key="ClaimsNameIdentifier" value="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier" />
    <add key="ClaimsUPNIdentifier" value="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn" />
    <add key="ClaimsEmailIdentifier" value="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" />
  </appSettings>

  <system.web>
    <authentication mode="None" />
    <compilation debug="true" targetFramework="4.7.1" />
    <httpRuntime targetFramework="4.7.1" />
  </system.web>

(注意:在上面的身份验证元素中,intellisense 给了我“Federated”作为选项,但这会导致编译错误)。

一个有用的资源是alligatortek ,但这并没有真正填满所有的部分。还有其他资源看起来很接近,但不够具体。

2019 年 2 月 12 日更新

根据以下评论,建议我改为关注 Vittorio Bertocci's post它使用“On-Premesis”选项(这与 Rober Finch's post 几乎相同)。生成的代码有点不同(见下文),但结果仍然相同。

Startup.Auth.cs

public partial class Startup
{
    private static readonly string realm = ConfigurationManager.AppSettings["ida:Wtrealm"];
    private static readonly string adfsMetadata = ConfigurationManager.AppSettings["ida:ADFSMetadata"];

    /// <summary>
    ///     Configures the authentication.
    /// </summary>
    /// <param name="app">The current application.</param>
    public void ConfigureAuth(IAppBuilder app)
    {
        app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
        app.UseCookieAuthentication(new CookieAuthenticationOptions());

        ServicePointManager.ServerCertificateValidationCallback = this.ValidateServerCertificate;
        app.UseWsFederationAuthentication(
            new WsFederationAuthenticationOptions
            {
                Wtrealm = Startup.realm,
                MetadataAddress = Startup.adfsMetadata
            });
    }

    private bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslpolicyerrors)
    {
        return true; // Skips certificate validation as using a temp certificate.
    }
}

Web.Config 中的部分

<appSettings>
    <add key="webpages:Version" value="3.0.0.0" />
    <add key="webpages:Enabled" value="false" />
    <add key="ClientValidationEnabled" value="true" />
    <add key="UnobtrusiveJavaScriptEnabled" value="true" />
    <add key="ida:ADFSMetadata" value="https://adfs.Mydomain.com/FederationMetadata/2007-06/FederationMetadata.xml" />
    <add key="ida:Wtrealm" value="https://myWebServer/myWebApplication" />
</appSettings>

最佳答案

终于解决了。

在 Startup.Auth.cs 文件中,我临时将以下行添加到 ConfigAuth(...) 方法中:

Microsoft.IdentityModel.Logging.IdentityModelEventSource.ShowPII = true;

然后这告诉我必须在 web.config 条目的“Wtrealm”值中添加尾部斜杠

所以来自:

<add key="ida:Wtrealm" value="https://myWebServer/myWebApplication" />

到:

<add key="ida:Wtrealm" value="https://myWebServer/myWebApplication/" />

关于asp.net-mvc - 如何在 ASP.NET MVC 中实现单点登录 (ADFS),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54541133/

相关文章:

authentication - 如何为运行在同一台服务器上的不同 ColdFusion 应用程序实现单点登录?

.net - 如何根据 X509Certificate2Collection 链验证 X509Certificate2

ios6 - iOS SDK 似乎无法处理 iOS 6 中已撤销的访问 token

.net - 是否可以对复杂的声明进行建模(分层/嵌套/等)?

c# - “Authorization has been denied for this request” 对于使用 Azure Active Directory 的少数用户

ADFS 4.0 (2016) OpenID Connect 用户信息端点在提供访问 token 时返回 401

c# - 尝试在 MVC4 和 Razor 上使用两个布局页面

asp.net - 如何让 Asp.net 将 Ext JS 表单提交识别为 Ajax 请求?

asp.net-mvc - 如何从多个模型中设置一个 Viewmodel?

c# - 流畅的 API = 数据注释?