0

I want to manually generate the authentication cookie string on the server side, that is generated by ASP .NET core when you have setup cookie authentication middleware and you sign-in the user using SignInAsync(this HttpContext context, string? scheme, ClaimsPrincipal principal). I am using a REST Client to make calls to API server. The APIs use cookie authentication. There is a use-case where once I receive a SAML response from IDP, there is an initial call I need to make to the API to get the user details. For that purpose I need to set the cookie in the request.

I am using ASP .NET Core 5 with cookie authentication setup in the Startup.cs file. It is typical cookie authentication middleware.

Below is sample code of what I am trying to do:

using MyProvider.Saml2Component;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Security.Claims;
using System.Threading.Tasks;


    [HttpPost]
    public async Task<IActionResult> SamlCallBack()
    {
        var samlResult = await _samlServiceProvider.ReceiveSsoAsync().ConfigureAwait(false);
        if (samlResult != null)
        {
            var email = samlResult.Attributes.FirstOrDefault(e => e.Name == "email").ToString();
            var id = samlResult.Attributes.FirstOrDefault(e => e.Name == "guid").ToString();

            var claims = new List<Claim>();

            if (!string.IsNullOrEmpty(email))
            {
                claims.Add(new Claim(ClaimTypes.Email, email));
            }

            if (!string.IsNullOrEmpty(id))
            {
                claims.Add(new Claim("SsoId", id));
            }

            var baseAddress = new Uri("http://example.com");
            var cookieContainer = new CookieContainer();
            using (var handler = new HttpClientHandler() { CookieContainer = cookieContainer })
            using (var client = new HttpClient(handler) { BaseAddress = baseAddress })
            {
                //How to get authentication cookie value here

                var ticket = GetSigninCookie(claims);
                cookieContainer.Add(baseAddress, new Cookie("CookieName", ticket));
                var result = await client.PostAsync("/user", null);
                result.EnsureSuccessStatusCode();
                var userDetails = await result.Content.ReadAsAsync<UserDetails>();
                var identity = new ClaimsIdentity();

                var signInClaims = new List<Claim>
                {
                    new Claim(ClaimTypes.NameIdentifier, userDetails.Id.ToString()),
                    new Claim("CompanyId", userDetails.CompanyId.ToString()),
                    new Claim(ClaimTypes.Name, userDetails.UserName)
                };
                identity.AddClaims(signInClaims);
                await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(identity));
                return RedirectToAction("Index", "Home");
            }


        }

        return View();
    }

    private string GetSigninCookie(List<Claim> claims)
    {
        throw new NotImplementedException();
    }
devanalyst
  • 1,348
  • 4
  • 28
  • 55
  • Excuse if I get the context wrong... But AFAIK, cookie should be send back to the response of `HttpClient` as we sign-in, which mean we got to extract and store that cookie content somewhere in our server. Then attach it with the request everytime we want to access the resource. We cannot make the cookie ourself and send it back to other API. – Gordon Khanh Ng. Nov 27 '21 at 15:25
  • If you really require cookies for your automated clients, then the proper solution for this is to have those clients persist cookies during their session and have them sign in properly first before making API requests. – poke Nov 28 '21 at 12:17
  • @poke, I have that as a workaround but that would mean one round trip to the client which I am trying to eliminate here – devanalyst Nov 30 '21 at 18:05
  • @devanalyst You will always have that round trip because how would you get the cookie value other than from the server? – poke Nov 30 '21 at 18:08

0 Answers0