API Key and JWT Authentication

Hi,

I have been reading through all of the ServiceStack documentation around API Key and JWT authentication.

As I am primarily a backend developer, I am struggling a bit with it.

Are there any examples / tutorials that make the task of converting our existing services that just use basic authentication to API Key / JWT authentication.

Many thanks in advance.

Simon

Note API Key and JWT are 2 different types of authentication methods so the first step is to workout what you want to move to and why?

You shouldn’t have to convert any existing Services implementations, i.e. each Auth Provider still uses the [Authenticate] attribute to authenticate Services and each Auth Provider still populates the Users Session.

The change would be how your clients authenticates, the C#/.NET Service Clients have support for both sending API Keys and sending JWT Tokens.

I guess I’m trying to figure out which part you’re having trouble with? Do you have specific code you’re using now that you want to change?

As I understood, the server side of the API all it needs is the new provider assign:

Plugins.Add(new AuthFeature(...,
    new IAuthProvider[] {
        new JwtAuthProvider(AppSettings) { AuthKey = AesUtils.CreateKey() },
        new CredentialsAuthProvider(AppSettings),
        //...
    }));

and on every client we need to append the token as

var authClient = JsonServiceClient(centralAuthBaseUrl) {
    Credentials = new NetworkCredential(apiKey, "")
};

or

var client = new JsonServiceClient(baseUrl);
client.OnAuthenticationRequired = () => {
    client.BearerToken = authClient.Send(new Authenticate()).BearerToken;
};

this alone will transform a SS API username/password authentication to JWT authentication, right?

1 Like

Yeah you’ll always need to register the AuthProviders you want to enabled. To enable API Keys you’ll need to register ApiKeyAuthProvider.

Then for Authenticating with an API key you can use either option:

//Sends API Key using HTTP Basic Auth
var client = new JsonServiceClient(baseUrl) {
    Credentials = new NetworkCredential(apiKey, "")
};

//Sends API Key using HTTP Bearer Token
var client = new JsonHttpClient(baseUrl) {
    BearerToken = apiKey
};

API Keys also require you to use a supported Auth Repository which will register API Keys for each new user that’s registered. If you want to enable API Keys to existing users you’ll need to generate API Keys for each user manually.

Hi,

Thank you very much for all the replies.

So, we currently use basic auth. We use the services from both a wpf and web forms application using the servicestack server side client libraries.

Our security is not ideal at the moment and we need to improve it.

I had initially looked at api key auth, but then noticed the JWT authentication.

The reason this took my interest is that we are currently migrating our old web forms app to an MVC app also using angular and implementing client side calls to our services.

We had tried client side calls in the past when using angular and hit real problems.

As I mentioned, I am not really a web dev, so can’t elaborate too much on the issues we had client side.

I would expect JWT is the best way to go taking this into account.

To be honest, I was just wanting to set up the repository code and was just struggling to find a definitive ax ample of how to do this correctly. The documentation is great, but just seems to show code snippets and I was trying to find a more complete example.

Perhaps I am over-complicating what I need to do and it is more straightforward than first appears.

It is just that my experience of web service authentication only extends as far as basic auth to date really.

Regards

Simon

Not sure JWT is what you want, JWT is generally used in addition with your existing Auth Providers to authenticate the User, then you can retrieve a JWT Token from your Authenticated Users Session. So it’s not a replacement for your existing Auth Providers, it’s an addition letting you use JWT’s to authenticate after you’re retrieved the JWT Token.

So my recommendation would be to get your other Auth Provider working first (e.g. CredentialsAuthProvider), then looking at enabling JWT as we’ve done in the examples below:

The Switching Sites to use JWT shows the different ways we’ve enabled JWT on existing sites in TechStacks with a single Ajax call:

$.post("/session-to-token");

Likewise Gistlyn uses the new Fetch API to convert an existing Github OAuth into a JWT Token Cookie:

fetch("/session-to-token", { method:"POST", credentials:"include" });

For our https://servicestack.net website we just changed the normal Username/Password Credentials Auth form and added an additional UseTokenCookie option as a hidden variable in our FORM request:

<form id="form-login" action="/auth/credentials">
    <input type="hidden" name="UseTokenCookie" value="true" />
    ...
    <input class="form-control" type="text" name="UserName" value="">
    ...
    <input class="form-control" type="password" name="Password">
</form>

Which instead of setting up a Users Session on the Server against ServiceStack’s ss-id/ss-pid Session Cookies it will create a JWT Token and add it to the ss-tok Cookie so each subsequent requests include the JWT Token in ss-tok and authenticates that way.

So other than the JWT Auth Provider registration in TechStacks and in Gistlyn, the above code is the really only thing we changed to change to use JWT Authentication in our Apps.

I can’t link to the private repo containing the servicestack.net website but this is basically our AuthFeature Registration:

Plugins.Add(new AuthFeature(() => new CustomUserSession(),
    new IAuthProvider[] {
        new CredentialsAuthProvider(appSettings), 
        new JwtAuthProvider(appSettings),
    }) {
        IncludeRegistrationService = true,
        MaxLoginAttempts = appSettings.Get("MaxLoginAttempts", 5),
    });

container.Register<IUserAuthRepository>(c =>
    new OrmLiteAuthRepository(c.Resolve<IDbConnectionFactory>()));

container.Resolve<IUserAuthRepository>().InitSchema();
3 Likes

Hi,

Sorry for the delayed reply.I have been away overnight.

Ah - OK. So if we are looking to use API Key auth instead of Basic Auth as we are at the moment, I should get that working and enable JWT on top of that.

This has all been really very helpful - thank you very much indeed.

I will go and get the API Key Auth working now.

Many thanks

Simon

2 Likes