【问题标题】:SSO Sustainsys.Saml2.Owin Request is not Authenticated - access_deniedSSO Sustainsys.Saml2.Owin 请求未通过身份验证 - access_denied
【发布时间】:2019-10-19 17:12:44
【问题描述】:

我必须使用 saml2 为我现有的 asp.net Web 应用程序进行 SSO 身份验证。

我正在使用 Sustainsys.Saml2.Owin 示例来执行此操作。

身份提供者是 Azure ADFS (https://sts.windows.net/TENANTID)

我已经配置了启动文件。它加载元数据文件和证书。

在我的登录页面中,如果未通过身份验证,我将面临挑战。

它已成功重定向到登录页面,但登录后请求从未获得身份验证。在回复 URL 中,我们得到 error=access_denied

[Request.IsAuthenticated 或 owinContext.Authentication.User.Identity.IsAuthenticated 均未设置为 true]

因此它会不断挑战多次,并因错误的请求而出错。

我做错了什么? Owin/Sustainsys 的哪个模块可以设置 IsAuthenticated 状态?

*一个 Saml2。 cookie [Saml2.DAeP63c***UTX0h***_***] 与登录 Microsoft 后的请求一起传递 [https://login.microsoftonline.com/TENANTID/saml2]

Startup.cs 文件

    public void ConfigureAuth(IAppBuilder appBuilder)
    {
        try
        {
            appBuilder.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

            appBuilder.UseCookieAuthentication(new CookieAuthenticationOptions());

            appBuilder.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);

            appBuilder.UseSaml2Authentication(CreateSaml2Options());
        }
        catch (Exception exp)
        {

        }
    }


    private Saml2AuthenticationOptions CreateSaml2Options()
    {
        try
        {
            var spOptions = CreateSPOptions();

            var Saml2AuthOptions = new Saml2AuthenticationOptions(false)
            {
                SPOptions = spOptions,
                Notifications = new Saml2Notifications(),
            };

            var idp = new IdentityProvider(new EntityId(authority), spOptions)
            {
                MetadataLocation = metadataLocation,
                Binding = Saml2BindingType.HttpRedirect
            };

            idp.SigningKeys.AddConfiguredKey(
                new X509Certificate2(certificateLocation));

            Saml2AuthOptions.IdentityProviders.Add(idp);

            return Saml2AuthOptions;
        }
        catch (Exception exp)
        {
        }
    }

    private SPOptions CreateSPOptions()
    {
        try
        {
            var engAus = "en-AU";

            var organization = new Organization();

            var spOptions = new SPOptions
            {
                EntityId = new EntityId(ApplicationId),
                ReturnUrl = new Uri(redirectUrl),
                Organization = organization,
            };

            return spOptions;
        }
        catch (Exception exp)
        {
        }
    }

Login.aspx.cs

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        IOwinContext owinContext = HttpContext.Current.GetOwinContext();

        //if (Request.IsAuthenticated)
        if (owinContext.Authentication.User != null &&
            owinContext.Authentication.User.Identity != null &&
            owinContext.Authentication.User.Identity.IsAuthenticated)
        {
            //Authenticated
            string name = owinContext.Authentication.User.Identity.Name;
        }
        else
        {
            var authenticationTypes = owinContext.Authentication.GetAuthenticationTypes().Select(d => d.AuthenticationType).ToArray();

            owinContext.Authentication.Challenge(new AuthenticationProperties { RedirectUri = "/" }, authenticationTypes);
        }
    }
}

【问题讨论】:

    标签: c# asp.net cookies single-sign-on sustainsys-saml2


    【解决方案1】:

    (此处发布的所有代码均来自 Github 的相同示例)

    您需要了解 SAML 的工作原理,这是我在深入研究 SustainsysSAML 之前使用的一个简单的 saml 实现类。 AspNetSaml

    这是SAML实现的基本流程:

    1. 用户访问您的应用程序,如果用户尚未通过身份验证,您的应用程序应将用户重定向到您的 saml 提供商。

      //specify the SAML provider url here, aka "Endpoint"
      var samlEndpoint = "http://saml-provider-that-we-use.com/login/";
      
      var request = new AuthRequest(
      "http://www.myapp.com", //put your app's "unique ID" here
      "http://www.myapp.com/SamlConsume" //assertion Consumer Url - the redirect URL where the provider will send authenticated users
      );
      
      //generate the provider URL
      string url = request.GetRedirectUrl(samlEndpoint);
      
      //then redirect your user to the above "url" var
      //for example, like this:
      Response.Redirect(url);
      
    2. 用户从 saml 提供者输入凭据,如果用户有效,则 saml 提供者将对用户进行身份验证并将用户重定向到您的应用。

    3. SAML 提供商会将 samlresponse 发布到您的应用程序(例如http://www.myapp.com/SamlConsum)。

      //ASP.NET MVC action method... But you can easily modify the code for Web-forms etc.
      public ActionResult SamlConsume()
      {
          //specify the certificate that your SAML provider has given to you
          string samlCertificate = @"-----BEGIN CERTIFICATE-----
      BLAHBLAHBLAHBLAHBLAHBLAHBLAHBLAHBLAHBLAHBLAHBLAH123543==
      -----END CERTIFICATE-----";
      
          Saml.Response samlResponse = new Response(samlCertificate);
          samlResponse.LoadXmlFromBase64(Request.Form["SAMLResponse"]); //SAML providers usually POST the data into this var
      
          if (samlResponse.IsValid())
          {
              //WOOHOO!!! user is logged in
              //YAY!
      
              //Some more optional stuff for you
              //lets extract username/firstname etc
              string username, email, firstname, lastname;
              try
              {
                  username = samlResponse.GetNameID();
                  email = samlResponse.GetEmail();
                  firstname = samlResponse.GetFirstName();
                  lastname = samlResponse.GetLastName();
              }
              catch(Exception ex)
              {
                  //insert error handling code
                  //no, really, please do
                  return null;
              }
      
              //user has been authenticated, put your code here, like set a cookie or something...
              //or call FormsAuthentication.SetAuthCookie() or something
          }
      }
      
    4. 您的应用程序将读取 samlresponse,如果有效,将允许用户使用您的应用程序,您的应用程序现在将根据您的策略处理用户的角色。

    一些提示:

    1. 确保您的应用程序可被您的 saml 提供商识别。
    2. 使用 Firebug 跟踪您的 http 请求(或任何 http 跟踪工具)
    3. 了解 samlresponse 和 samlrequest 之间的区别
    4. 使用 Firebug,您应该能够看到 samlresponse。
    5. 如果您有多个 Web 应用程序,您希望使用您的 saml 提供程序进行 SSO。我建议您创建一个 httprequest/httphandler 来处理来自您的提供商的 samlresponse。然后,您可以将此 dll 安装到您的服务器,并将处理程序添加到每个 Web 应用程序的配置中。您的网络应用程序无需更改代码:)。

    我希望这会有所帮助。

    【讨论】:

    • 链接在我上面的答案中,正如我在答案的第一行中所说的那样。 (这里发布的所有代码都是来自 Github 的相同示例)
    • 我的问题实际上是,在 Request.Form 中没有收到“SAMLResponse”。
    • 我能看到的只是一个 cookie [Saml2. cookie] 在请求中。我该如何处理?
    • 当您的 SAMLProvider 将 SAMLResponse 发布到您的站点时,您应该能够使用 Firebug 看到它。
    • 是的。我正在使用萤火虫。但没有 SAMLResponse
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-05-19
    • 2021-08-04
    • 1970-01-01
    • 2015-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多