0

我必须为我现有的 asp.net Web 应用程序使用 saml2 进行 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]

启动.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)
        {
        }
    }

登录.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);
        }
    }
}
4

1 回答 1

4

(此处发布的所有代码都是来自 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 应用程序的配置中。您的网络应用程序无需更改代码:)。

我希望这有帮助。

于 2019-06-07T00:45:46.033 回答