本文介绍了SSO Sustainsys.Saml2.Owin请求未通过身份验证-access_denied的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have to do SSO authentication with saml2 for my existing asp.net web application.

我正在使用Sustainsys.Saml2.Owin示例来做到这一点.

I am using Sustainsys.Saml2.Owin example to do that.

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

Identity provider is Azure ADFS ( https://sts.windows.net/TENANTID )

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

I have configured the Startup file. It loads the metadata file and certificate.

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

And in my Login page, I am challenging if not authenticated.

它已成功重定向到登录页面,但登录后永远不会对请求进行身份验证.在回复URL中,我们得到 error = access_denied

It is successfully redirecting to the login page but the Request is never getting authenticated after the login. And in the reply URL we are getting error=access_denied

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

[neither Request.IsAuthenticated or owinContext.Authentication.User.Identity.IsAuthenticated is set to true]

因此,它会持续挑战很多次,并因请求错误而出错.

So it keep on challenging for many times and error with bad request.

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

What I am doing wrong? Which module of Owin/Sustainsys is reposnsible to set the IsAuthenticated status?

* a Saml2.登录到Microsoft [ https://login.microsoftonline.com/TENANTID/saml2]

*a Saml2. cookie [Saml2.DAeP63c***UTX0h***_***] is passed along with the request after login into 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);
        }
    }
}

推荐答案

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

(all code posted here are the same sample from Github)

您需要了解SAML的工作原理,这是我学习SustainsysSAML之前使用的一个简单的saml实现类. AspNetSaml

You need to understand how SAML works, here's a simple saml implementation class that I used before I dive into SustainsysSAML. AspNetSaml

这是SAML实现的基本流程:

This is the basic flow of SAML Implementation:

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

  1. User access your app, if user is not yet authenticated your app should redirect the user to your saml provider.

//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);

  • 从saml提供程序中,用户输入凭据,如果有效用户,saml提供程序将对用户进行身份验证并将其重定向到您的应用.

  • From saml provider, user enters credentials and if valid user, saml provider will authenticate and redirect the user to your app.

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

    SAML provider will post the samlresponse to your app (eg. 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
        }
    }
    

  • 您的应用程序将读取samlresponse,如果有效,将允许用户使用您的应用程序,您的应用程序现在将根据您的策略处理用户的角色.

  • Your app will read the samlresponse and if valid will let the user use your app, your app will now handle the roles of the user depending on your policies.

    一些提示:

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

    我希望这会有所帮助.

    这篇关于SSO Sustainsys.Saml2.Owin请求未通过身份验证-access_denied的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

  • 10-16 21:49