I have an asp net core application developed with .NET 5.
In this application, there is a controller (ACSController) that manages responses from an Identity Provider. The controller is the follow:
public class ACSController : Controller
{
private readonly IRequestRepository _requestRepository;
private readonly IHttpClientFactory _httpClientFactory;
private readonly IIdpRepository _idpRepository;
private readonly IResponseRepository _responseRepository;
private readonly AppSessionViewModel _session;
public ACSController(IRequestRepository requestRepository, IHttpClientFactory httpClientFactory,
IIdpRepository idpRepository, IResponseRepository responseRepository, AppSessionViewModel session)
{
_requestRepository = requestRepository;
_httpClientFactory = httpClientFactory;
_idpRepository = idpRepository;
_responseRepository = responseRepository;
_session = session;
}
[HttpPost]
public async Task<IActionResult> IndexAsync(IFormCollection form)
{
var base64Response = form["SAMLResponse"].ToString();
var response = SAMLHelper.GetAuthnResponse(base64Response);
var cachedRequest = _requestRepository.Read();
var idpMetadata = await SamlHandler.DownloadIdPMetadata(_httpClientFactory,
_idpRepository.Read().OrganizationUrlMetadata);
var validationResult = ResponseValidator.ValidateAuthnResponse(response, cachedRequest, idpMetadata);
if (validationResult.IsSuccess)
{
_responseRepository.Write(response);
_session.Logged = true;
ViewData["UserInfo"] = CreateUserInfo(response);
return View();
}
else
{
ViewData["Message"] = validationResult.Error;
return View("Error");
}
}
[HttpPost]
public IActionResult Logout(IFormCollection form)
{
var base64Response = form["SAMLResponse"].ToString();
return View();
}
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error()
{
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}
#region Utilities
private Dictionary<string, string> CreateUserInfo(AuthnResponse response)
{
if (response == null) throw new ArgumentException(nameof(response));
var attributes = response.GetAssertion().GetAttributeStatement().Items;
var userDictionary = new Dictionary<string, string>();
foreach (var attribute in attributes)
{
var attr = (AttributeType)attribute;
userDictionary.Add(attr.Name, (string)attr.AttributeValue.First());
}
return userDictionary;
}
#endregion
}
In my case, there is no problem when acs/index method is called by a POST request.
When I invoke the Logout procedure (from another controller) the request is sent correctly by my application but when IdP responds to me I obtain this response on my browser:
Update:
If you want to decode a base64string,try to use:
byte[] data = Convert.FromBase64String(SAMLResponse);
string decodedString = Encoding.UTF8.GetString(data);