I am working on creating an identity microservice using the .NET Identity platform and the new Identity API endpoints. I have 3 separate applications that I am using for testing of the service: An identity api that validates user credentials and creates an authorization cookie, a client razor pages application that sends a post request to my Identity API and should receive the cookie to authenticate future requests, and a test API to serve as a dummy microservice. The Test API should be authenticated by the Identity API cookie.
Identity API Program.cs:
using IdentityService.Data;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using System.Security.Claims;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddAuthorization();
builder.Services.AddAuthentication().AddCookie(IdentityConstants.ApplicationScheme)
.AddBearerToken(IdentityConstants.BearerScheme);
builder.Services.AddIdentityCore<User>()
.AddEntityFrameworkStores<AppDBContext>()
.AddApiEndpoints();
builder.Services.AddDbContext<AppDBContext>(options =>
{
options.UseSqlServer(builder.Configuration.GetConnectionString("IdentityDatabase"));
});
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.MapIdentityApi<User>();
app.Run();
Client Web App PageModel Post Method for Login Call
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
LoginRequest request = new LoginRequest
{
Email = Request.Form["Email"],
Password = Request.Form["Password"]
};
HttpClient client = _httpClientFactory.CreateClient("Auth");
HttpResponseMessage response = await client.PostAsJsonAsync(new Uri(client.BaseAddress + "login?useCookies=true"), request);
string content = await response.Content.ReadAsStringAsync();
if (response.IsSuccessStatusCode)
{
return RedirectToPage("./Test");
}
return RedirectToPage("./Index");
}
Test API Program.cs
using Microsoft.AspNetCore.DataProtection;
using Microsoft.AspNetCore.Identity;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddAuthentication(IdentityConstants.ApplicationScheme);
builder.Services.AddAuthorizationBuilder()
.AddPolicy("api", p =>
{
p.RequireAuthenticatedUser();
p.AddAuthenticationSchemes(IdentityConstants.ApplicationScheme);
});
builder.Services.AddDataProtection().PersistKeysToFileSystem(new DirectoryInfo(@"c:temp-keys")).SetApplicationName("IdentityService.API");
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.MapGet("api/foo", () =>
{
return new[] { "One", "Two", "Three" };
})
.RequireAuthorization("api");
app.Run();
Test API Controller Endpoint Im trying to hit from client app after being logged in:
namespace IdentityService.TestAPI.Controllers
{
[Route("api/[controller]")]
[ApiController]
[Authorize("api")]
public class TestController : ControllerBase
{
private readonly ILogger<TestController> _logger;
public TestController(ILogger<TestController> logger)
{
_logger = logger;
}
[HttpGet]
public string Get()
{
return "Test API returned Successfully";
}
}
}
When I pass my login credentials to the client application and get a successful response, I don’t get the cookie in my browser that I anticipate:
But I do get a cookie as expected if I log in using Swagger:
How can I get this cookie in my client application, and pass it to my test application to authenticate my endpoint?
I have looked at the documentation on sharing cookies across applications from Microsoft, but Im not sure which application needs the lines of code referenced. I’ve tried a few different combinations but none seems to work as expected.
https://learn.microsoft.com/en-us/aspnet/core/security/cookie-sharing?view=aspnetcore-8.0