Using JWT in JsonApiClient in Blazor WASM Example .NET 7

I am trying to extend Blazor WASM Example to use JWT tokens generated by my services.

I am able to make the call to the service to get a token, then I set this on a JsonApiClient to test (this is because I couldn’t get it to work in with the Auth in Blazor).

However when you set a BearerToken in the JsonApiClient, you get the following exception trying to make a call:

'PlatformNotSupportedException' Operation is not supported on this platform.
  at System.Net.Http.BrowserHttpHandler.set_Credentials(ICredentials value)
   at System.Net.Http.HttpClientHandler.set_UseDefaultCredentials(Boolean value)
   at ServiceStack.JsonApiClient.GetHttpClient() in /home/runner/work/ServiceStack/ServiceStack/ServiceStack/src/ServiceStack.Client/JsonApiClient.cs:line 181
   at ServiceStack.JsonApiClient.<SendAsync>d__156`1[[ServiceStack.AuthenticateResponse, ServiceStack.Client, Version=6.0.0.0, Culture=neutral, PublicKeyToken=null]].MoveNext() in /h…thenticateResponse, ServiceStack.Client, Version=6.0.0.0, Culture=neutral, PublicKeyToken=null]].MoveNext() in /home/runner/work/ServiceStack/ServiceStack/ServiceStack/src/ServiceStack.Client/JsonApiClient.cs:line 284
   at ServiceStack.ApiResultUtils.<ApiAsync>d__4`1[[ServiceStack.AuthenticateResponse, ServiceStack.Client, Version=6.0.0.0, Culture=neutral, PublicKeyToken=null]].MoveNext() in /home/runner/work/ServiceStack/ServiceStack/ServiceStack/src/ServiceStack.Client/ApiResult.cs:line 227

I am just trying to do the following:

        var jsonClient = new JsonApiClient("https://localhost:3000")
        {
            BearerToken = "MyToken"
        };
        var authApi = await jsonClient.ApiAsync(new Authenticate());
        var authResponse = authApi.Response;

You can’t use JsonApiClient directly in Blazor WASM, you’ll need to register the Blazor HttpClient factory as done in the blazor-tailwind project template, e.g:

Which will be injected into your components that inherit ServiceStack’s AppComponentBase or AppAuthComponentBase where you can access it from base.Client or use its managed ApiAsync() APIs.

Otherwise your custom components can access it like:

public class MyComponent : ComponentBase
{
    [Inject] public IClientFactory? ClientFactory { get; set; }
    public JsonApiClient Client => ClientFactory!.GetClient();
}

I can see from the docs maybe I shouldn’t be using JsonApiClient, but I’m only trying to do this because setting BearerToken on the JsonApiClient in Auth never sends any Authorization header.

I am forking blazor-tailwind project for this.

image

No Authorization header on the Request:

It’s only recommended to use JWT with HTTP Only Cookies in SPAs like Blazor WASM otherwise they’ll be vulnerable to XSS attacks.

BearerToken would need to be set before the HttpClient instance is created. You can try setting the Authorization Header on the existing HttpClient instance with:

Client.GetHttpClient().DefaultRequestHeaders.Authorization = 
    new AuthenticationHeaderValue("Bearer", BearerToken);

If your Blazor WASM client is hosted on a different domain than the APIs they’re calling, you’ll also need to allow the Authorization Header in CorsFeature with:

I see… thanks for the help that does pass the Authorization header.
I’ll have a think about the best way to move to Cookie based tokens.

It’s only because my Auth is not a typical User/Password + Database store, but a signed Ethereum message indicating control of a particular address that I didn’t write a ServiceStack.Auth.AuthProvider

Many thanks for your assistance.

Changing my app to set ss-tok as well as return a JWT Token in the response, Secure=false (I am running over HTTPS anyway for now, API will be behind CloudFront eventually.

Unfortunately it doesn’t send ss-tok when making the next /api/Authenticate call.

It doesn’t seem to send ss-id either but I’m not certain of the intended use of this cookie.

1 Like

Find out why it’s not sending Browser Cookies, are there any warnings in the console? Are you sending it over https?

Thanks for your help mythz. Browser stuff from here on, thanks for the time responding to the ServiceStack questions.

Different scheme? Are both sites not being served over https?

They are not, this did resolve it.
Probably worth me just creating an API shim just for the Web API that can be on the same host, and another for API Clients.