Implementing Custom Authentication in ServiceStack.NET

I’m not an expert of Authorization & Authentication concepts but recently I needed a basic authentication mechanism for my personal website uses ServiceStack.NET.

I made a little research and found official guide. I encountered a lot of stuff, some concepts that I am not familiar with. Then I decided to implement a custom authentication for my website.

1. Create a custom auth provider

To make your ServiceStack services secure, first thing you need to do is creating a class extends CredentialsAuthProvider class. This class is used to authenticate clients with Credentials like username-password.

This class will behave like a kind of adapter, between your implementation and ServiceStack authorization engine. A few virtual methods is exists, but we don’t need to override for our basic implementation.

2. Enabling Authentication

Next step is enabling Authentication. Copy and paste the code below to your AppHost constructor located in Startup.cs.

Now we declared that we need secured services, and will use our CustomAuthProvider for this concern. By doing this, ServiceStack enables the /auth/{provider} endpoint to authenticate clients.

Let’s make a request to /auth/credentials endpoint and see what we get.

POST /auth/credentials?format=json HTTP/1.1
Host: localhost:5000
Authorization: Bearer j5Njuu8h3Qn2uNUf1qCu
Content-Type: application/json
Cookie: ss-opt=temp; X-UAId=; ss-id=oGU9jxEyFFyTuMuJqROr; ss-pid=BjF5pv63Yx3ApNZJ2UPE
{
"UserName":"fatih",
"Password":"123456"
}

We got an exception that tells us ‘’No IAuthRepository registered in IoC or failed to resolve.’. This means our application isn’t able to validate given credentials. Actually, doesn’t know how to validate given credentials.

{"responseStatus": {
"errorCode": "Exception",
"message": "No IAuthRepository registered in IoC or failed to resolve.",
"stackTrace": "[Authenticate: 31.10.2020 20:47:51]:\n[REQUEST: {provider:credentials,userName:fatih,password:07010407}]\r\nSystem.Exception: No IAuthRepository registered in IoC or failed to resolve.\r\n
...
...
}

At this point UserAuthRepository comes to the stage to implement validating user credentials logic.

3. Create a UserAuthRepository

Next step is building a bridge between our persistance and our AuthProvider. This bridge is called ‘UserAuthRepository’. We will implement the logic of validating user credentials, fetching user information and registering a user. ServiceStack gives an interface for this work called IUserAuthRepository. It’s a interface to access underlying user and role data store.

Let’s create a class named CustomAuthRepository implements IUserAuthRepository.

This interface a lot of method to implement. I only implemented TryAuthenticate(), GetUserAuthByUserName(), GetUserAuth(), DeleteUserAuth(), CreateUserAuth(). You can implement all of those if you would like. But the above will suffice for basic authentication logic.

The application is using EntityFrameworkCore for persistance concerns, so I used a DbContext object to build this bridge.

Basicly, I encrypted the password received with MD5 algorithm, and I compared the hash with the password persisted in Users table. If there is a match, our TryAuthenticate() method simply returns true.

4. Register CustomAuthRepository to the IoC Container

ServiceStack uses a built-in IoC container to resolve ServiceStack’s internal dependencies. We need to register our CustomAuthRepository to the container.

Paste the code below to the Configure() method located in your AppHostBase implementation.

Let’s make another request to /auth/credentials endpoint and see what we get this time.

If our logic in CustomAuthRepository is correct, we should get a response like below includes a sessionId which will be used to access to secured services.

{
"sessionId": "WH7WLsT2hUvokp7WNoyi",
"userName": "fatih",
"displayName": "Fatih DUMANLI",
..............
"responseStatus": {}
}

5. Make your ServiceStack services secured

Now our application is has a primitive authentication mechanism. Next thing to do is marking the services we would like it to be secured with [Authenticate] attribute.

After marking your services with [Authenticate] attribute, you can use HTTP authorization header to access those services. An example request is shown below.

POST /site/set/fullname HTTP/1.1
Host: localhost:5000
Authorization: Bearer i5e4l7LCZyFhwimQ2bjV
Content-Type: application/json
Cookie: ss-opt=temp; X-UAId=; ss-id=WH7WLsT2hUvokp7WNoyi; ss-pid=PuPdSywVekjQADZqeTSg
{
"FullName":"fatih dumanli"
}

We pass our sessionId in Authorization header. With this request we are going to get 200 from our secured ServiceStack services.

For more information you can check the official guide.

If this post helped you or learned something, please give a clap :)

Backend Software Engineer https://github.com/fatihdumanli