Sustainsys / Saml2

Saml2 Authentication services for ASP.NET
Other
940 stars 606 forks source link

Return Challenge Destination Instead of Redirecting #1425

Closed innotech-banha closed 5 months ago

innotech-banha commented 6 months ago

Hello,

Sorry for keeping to bother with questions. We're using the package Sustainsys.Saml2.AspNetCore2 (version 2.9.2) for .NET 6.

Is there a way to return the address with the SamlRequest to the caller of an API that is using your package, instead of having the library redirecting the user?

I ask, because we're having trouble when trying to do this from the API only. We suspect that if it was the Front-End application redirecting, that it could work.

This is the code where we're adding SAML:

public static AuthenticationBuilder AddSaml2Authentication(this IServiceCollection services, IConfiguration configuration)
{
    var saml2Configuration = new Saml2Configurations();
    configuration.Bind(ConfigurationKey, saml2Configuration);
    return services.AddAuthentication(options =>
    {
        options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;

        options.DefaultChallengeScheme = Saml2Defaults.Scheme;
    })
    .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, (options) =>
    {
        options.LoginPath = GetLoginPath(configuration);
        options.ReturnUrlParameter = "redirectUrl";
    })
    .AddSaml2(options =>
    {
        options.SPOptions.EntityId = new EntityId(saml2Configuration.SPEntityId);
        options.IdentityProviders.Add(new IdentityProvider(
        new EntityId(saml2Configuration.IdPEntityId),
        options.SPOptions)
        {
            MetadataLocation = saml2Configuration.IdPMetadataLocation
        });
    });
}

And this is the controller that takes care of the authentication:


public class AccountController : Controller
{
    [AllowAnonymous]
    [HttpGet("Login")]
    public IActionResult Login(string redirectUrl)
    {
        string? redirectUri = Url.Action(nameof(LoginCallback), new { redirectUrl });
        var properties = new AuthenticationProperties()
        {
            RedirectUri = redirectUri
        };
        ChallengeResult result = Challenge(properties, Saml2Defaults.Scheme);
        return result;
    }

    [AllowAnonymous]
    [HttpGet("Callback")]
    public async Task<IActionResult> LoginCallback(string redirectUrl)
    {
        AuthenticateResult authenticateResult = await HttpContext.AuthenticateAsync(CookieAuthenticationDefaults.AuthenticationScheme);
        if (!authenticateResult.Succeeded)
        {
            return Unauthorized();
        }
        IEnumerable<Claim>? claimCollection = authenticateResult.Principal?.Claims;
        if (claimCollection == null || !claimCollection.Any())
        {
            return Problem(statusCode: StatusCodes.Status400BadRequest);
        }
        if (!string.IsNullOrEmpty(redirectUrl))
        {
            return Redirect(redirectUrl);
        }
        return Ok();
    }
}```
AndersAbel commented 5 months ago

No, there is no built in way to do that. But it can be done through some customizations - either in how the library is used or possibly as a separate middleware that converts the response. I'd be happy to help out under my commercial support contract, please get in touch at support@sustainsys.com for more information.