我必须为现有的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状态?
* a Saml2。登录到Microsoft [https://login.microsoftonline.com/TENANTID/saml2]
后, cookie 与请求一起传递了[Saml2.DAeP63c *** UTX0h *** _ ***]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);
}
}
}
答案 0 :(得分:1)
(此处发布的所有代码都是来自Github的同一示例)
您需要了解SAML的工作原理,这是我学习SustainsysSAML之前使用的一个简单的saml实现类。 AspNetSaml
这是SAML实现的基本流程:
用户访问您的应用程序,如果尚未通过用户身份验证,则您的应用程序应将用户重定向到您的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);
从saml提供程序中,用户输入凭据,如果有效用户,saml提供程序将对用户进行身份验证并将其重定向到您的应用。
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
}
}
您的应用程序将读取samlresponse,并且如果有效将使用户使用您的应用程序,则您的应用程序现在将根据您的策略来处理用户的角色。
一些提示:
我希望这会有所帮助。