+xThe OnSamlResponseCreated event provides you with access to the SAML response.
For example:
private Task CompleteSsoAsync()
{
_samlIdentityProvider.Events.OnSamlResponseCreated = (context, samlResponse) =>
{
// Send the SAML response or save it for sending later - not shown.
return samlResponse;
};
// Get the name of the logged in user.
var userName = User.Identity.Name;
// For demonstration purposes, include some claims.
var attributes = new List<SamlAttribute>()
{
new SamlAttribute(ClaimTypes.Email, User.FindFirst(ClaimTypes.Email)?.Value),
new SamlAttribute(ClaimTypes.GivenName, User.FindFirst(ClaimTypes.GivenName)?.Value),
new SamlAttribute(ClaimTypes.Surname, User.FindFirst(ClaimTypes.Surname)?.Value),
};
// The user is logged in at the identity provider.
// Respond to the authn request by sending a SAML response containing a SAML assertion to the SP.
return _samlIdentityProvider.SendSsoAsync(userName, attributes);
}
I'm not sure how you intend to send the SAML response but you could either send it or save it for later sending from the OnSamlResponseCreated event.
If you also want to stop the SAML response being returned to the browser in the HTTP response as part of the SAML protocol, you can implement the IHttpResponse interface so that the HTTP response is written to a memory stream and therefore doesn't go anywhere.
For example:
public class NopHttpResponse : IHttpResponse
{
public string ContentType { get; set; }
public Stream Body { get; set; } = new MemoryStream();
public void AddCookie(string cookieName, string cookieValue,
ComponentSpace.Saml2.Bindings.CookieOptions cookieOptions)
{
}
public void AddHeader(string headerName, StringValues headerValues)
{
}
public void Redirect(string url)
{
}
}
You register this implementation at start-up as follows:
// Add SAML SSO services.
services.AddSaml(Configuration.GetSection("SAML"));
services.AddTransient<IHttpResponse, NoHttpResponse>();
It would be good to have a better understanding of your requirements to see if there's a better solution. Sending an XML signed SAML response message as JSON is very unusual.
Thanks for your reply, below is the saml code.
public async Task GenerateAssertion(string AppId, string Email)
{
var resp = new ApiResponse
{
responseCode = 0
};
try
{
if (!string.IsNullOrWhiteSpace(Email) && !string.IsNullOrWhiteSpace(AppId))
{
var userName = string.Empty;
var partnerName = string.Empty;
foreach (var item in _samlConfigurations.Configurations)
{
partnerName = item.PartnerServiceProviderConfigurations.Select(x => x.Name).FirstOrDefault();
}
userName = Email;
var attributes = new List<SamlAttribute>()
{
new SamlAttribute(ClaimTypes.Email, Email),
new SamlAttribute("NameID", Email),
};
var response = _samlIdentityProvider.Events.OnSamlResponseCreated = (context, samlResponse) =>
{
// Send the SAML response or save it for sending later - not shown.
var test = samlResponse.ToXml();
var xmlAssertion = samlResponse.ToXml().OuterXml;
return samlResponse;
};
//Here is there a way not to inititate SSO and not to redirect to ACS url.
//I will be using samlResponse as string/xml and we need to send it to our internal method, where
// we will will sending it as object in response. Primary authentication is different, we need this assertion
// as addition.
_ = _samlIdentityProvider.InitiateSsoAsync(partnerName, userName, attributes, null, null);
}
else
{
_ = Task.Run(() => _logService.Info("Processing SamlController - Invalid Email"));
}
}
catch (Exception ex)
{
resp.responseMessage = "Unexpected error occured.";
_ = Task.Run(() => _logService.Error("Error in SamlController - Inititate SSO :" + ex));
}
}
Basically we need only assertion as one of the requirement. Here is there a way not to inititate SSO and not to redirect to ACS url.
I will be using samlResponse as string/xml and we need to send it to our internal method, where
we will will sending it as object in response. Primary authentication is different, we need this assertion
as addition parameter.