.NET Framework 4.7 API v2 doesn't see call from Blazor server as authenticated

40 Views Asked by At

I feel like I'm really close to solving this, since I must be from mashing keystrokes for 4 days straight. :)

Here's the env:

  • Legacy .NET Framework 4.7 (app 1) has login form (Owin packages below) with anonymous API endpoints for querying user and cart data.
  • Blazor server .NET 6.0 (app 2) is hosting a new Checkout page that needs to call APIs from app 1 and retrieve user name/id, which will be used to get cart data
  • app 1 user status endpoint returns 401 / Unauthorized
  • app 1: Microsoft.Owin 3.0.1, Microsoft.AspNet.Identity.Owin 2.2.1
  • app 2: Microsoft.Owin.Security 4.2.2, Microsoft.Owin.Security.Cookies 4.2.2

Here's the user status api endpoint that app 1 has exposed:

[AllowAnonymous, HttpGet, Route("api/account/status")]
[EnableCors("*", headers: "*", methods: "*")]
public HttpResponseMessage Status()
{            
    var response = this.Request.CreateResponse(this.User.Identity.IsAuthenticated ? HttpStatusCode.OK : HttpStatusCode.Unauthorized, this.User.Identity.GetUserName());
    return response;
}

However, User.IsAuthenticated is never true, so the response always returns "Unauthorized" and it doesn't call GetUserName().

In app 2, I'm using IJSRuntime to call a javascript fetch(), which calls the endpoint above. Index.razor:

protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            await GetUserNameAsync();
        }
    }

private static Task<AuthenticationState> GenerateEmptyAuthenticationState() => Task.FromResult(new AuthenticationState(new ClaimsPrincipal()));

    /// <summary>
    /// Calls site.js > returnUserNameAsync() that retrieves the UserName from an API call to TL.Web
    /// </summary>
    /// <returns></returns>
    private async Task<string> GetUserNameAsync()
    {
        return await JS.InvokeAsync<string>("returnUserNameAsync");
    }

In site.js:

window.returnUserNameAsync = () => {
    let userApiUrl = "http://localhost:55052/api/account/status";

    fetch(userApiUrl, {
        credentials: "same-origin"
    })
        .then(data => data.json())
        .then(data => console.log(data))
        .catch(err => console.log('Request failed:', err));
};

When app 1 logs in, the .AspNet.ApplicationCookie is set. Since the Blazor js call is client-side, do I have to do anything further with the cookie to authenticate? What does app 1 additionally need from app 2?

I've searched like a bandit for 4 days and can't seem to find the right code mash combo. Any examples would be so greatly appreciated!

0

There are 0 best solutions below