Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Built into ServiceStack is an optional Authentication feature you can use to add Authentication to your services by providing web services to Authenticate existing users, Register new users as well Assign/UnAssign Roles to existing users (if you need them). It's highly pluggable and customizable where you can plug-in your own Auth logic, change the caching and session providers as well as what RDBMS is used to persist UserAuth data.

A minimal configuration needed to get Basic Authentication up and running is the following in AppHost.Config() (derived from the AuthTests unit test):

public override void Configure(Container container)
{
    Plugins.Add(new AuthFeature(() => new AuthUserSession(),
      new IAuthProvider[] { 
        new BasicAuthProvider(), //Sign-in with Basic Auth
        new CredentialsAuthProvider(), //HTML Form post of UserName/Password credentials
      }));

    Plugins.Add(new RegistrationFeature());

    container.Register<ICacheClient>(new MemoryCacheClient());
    var userRep = new InMemoryAuthRepository();
    container.Register<IUserAuthRepository>(userRep);

    //The IUserAuthRepository is used to store the user credentials etc.
    //Implement this interface to adjust it to your app's data storage
}

The high-level overview below shows how all the different parts fit together and which parts are customizable:

Authentication Overview

Auth Providers

From the overview we can see the built-in AuthProviders that are included:

  • Credentials - For authenticating with username/password credentials by posting to the /auth/credentials service
  • Basic Auth - Allowing users to authenticate with Basic Authentication
  • Digest Auth - Allowing users to authenticate with HTTP Digest Authentication
  • Custom Credentials - By inheriting CredentialsAuthProvider and providing your own Username/Password TryAuthenticate implementation
  • Twitter OAuth (open standard for authorization) - Allow users to Register and Authenticate with Twitter
  • Facebook OAuth - Allow users to Register and Authenticate with Facebook
  • Yammer OAuth - Allow users to Register and Authenticate with Yammer

OpenId Auth Providers

The ServiceStack.Authentication.OpenId NuGet package provides OpenId Auth Providers support to ServiceStack that includes:

  • Google OpenId - Allow users to Register and Authenticate with Google
  • Yahoo OpenId - Allow users to Register and Authenticate with Yahoo
  • MyOpenId - Allow users to Register and Authenticate with MyOpenId
  • OpenId - Allow users to Register and Authenticate with any custom OpenId provider

Find more info about OpenId 2.0 providers on the wiki.

OAuth2 Providers

The ServiceStack.Authentication.OAuth2 NuGet package provides OAuth2 Providers support to ServiceStack that includes:

  • Google OAuth2 - Allow users to Register and Authenticate with Google OAuth2
  • LinkedIn OAuth2 - Allow users to Register and Authenticate with LinkedIn OAuth2

OAuth Configuration

The OAuth providers below require you to register your application with them in order to get the ConsumerKey and ConsumerSecret required, at the urls below:

AuthWebTests is a simple project that shows all Auth Providers configured and working in the same app. See the AppHost for an example of the code and the Web.config for an example of the configuration required to enable each Auth Provider.

Once you have the ConsumerKey and ConsumerSecret you need to configure it with your ServiceStack host, via Web.config, e.g:

<add key="oauth.twitter.RedirectUrl"    value="http://yourhostname.com/"/>
<add key="oauth.twitter.CallbackUrl"    value="http://yourhostname.com/auth/twitter"/>    
<add key="oauth.twitter.ConsumerKey"    value="3H1FHjGbA1N0n0aT5yApA"/>
<add key="oauth.twitter.ConsumerSecret" value="MLrZ0ujK6DwyjlRk2YLp6HwSdoBjtuqwXeHDQLv0Q"/>

Note: Each OAuth Config option fallbacks to the configuration without the provider name. This is useful for reducing repetitive configuration that's shared by all OAuth providers like the RedirectUrl or CallbackUrl, e.g:

<add key="oauth.RedirectUrl"    value="http://yourhostname.com/"/>
<add key="oauth.CallbackUrl"    value="http://yourhostname.com/auth/{0}"/>    

Or via configuration in code when you register the AuthFeature in your AppHost, e.g:

Plugins.Add(new AuthFeature(() => new AuthUserSession(), new IAuthProvider[] {
    new TwitterAuthProvider(appSettings) { 
        RedirectUrl = "http://yourhostname.com/",
        CallbackUrl = "http://yourhostname.com/auth/twitter",
        ConsumerKey = "3H1FHjGbA1N0n0aT5yApA",
        ConsumerSecret = "MLrZ0ujK6DwyjlRk2YLp6HwSdoBjtuqwXeHDQLv0Q",
    },
}));

Note: The Callback URL in each Application should match the CallbackUrl for your application which is typically: http://yourhostname.com/auth/{Provider}, e.g. http://yourhostname.com/auth/twitter for Twitter.

Built-In Auth Providers

By default the CredentialsAuthProvider and BasicAuthProvider validate against users stored in the UserAuth repository. The registration service at /register allow users to register new users with your service and stores them in your preferred IUserAuthRepository provider (below). The SocialBootstrapApi uses this to allow new users (without Twitter/Facebook accounts) to register with the website.

A good starting place to create your own Auth provider that relies on username/password validation is to subclass CredentialsAuthProvider and override the bool TryAuthenticate(service, username, password) hook so you can add in your own implementation. If you want to make this available via BasicAuth as well you will also need to subclass BasicAuthProvider with your own custom implementation.

UserAuth Persistence - the IUserAuthRepository

The Authentication module allows you to use your own persistence back-ends but for the most part you should be able to use one of the existing InMemory, Redis, OrmLite, MongoDB or NHibernate adapters. Use the OrmLite or NHibernate adapter if you want to store the Users Authentication information in any of the RDBMS's that OrmLite supports, which as of this writing includes Sql Server, Sqlite, MySql, PostgreSQL and Firebird.

Caching / Sessions - the ICacheClient

Once authenticated the AuthUserSession model is populated and stored in the Cache using one of ServiceStack's supported Caching providers. ServiceStack's Sessions simply uses the ICacheClient API so any new provider added can be used for both Session and Caching options. Which currently include the following implementations:

The Auth Feature also allows you to specify your own custom IUserAuthSession type so you can attach additional metadata to your users session which will also get persisted and hydrated from the cache.

Note: If you're using Custom Sessions and have JsConfig.ExcludeTypeInfo=true, you need to explicitly enable it with JsConfig<TCustomSession>.IncludeTypeInfo=true.

After authentication the client will receive a cookie with a session id, which is used to fetch the correct session from the ICacheClient internally by ServiceStack. Thus, you can access the current session in a service:

public class SecuredService : Service
{
    public object Get(Secured request)
    {
        IAuthSession session = this.GetSession();
        return new SecuredResponse() { Test = "You're" + session.FirstName };
    }
}

ServiceStack's Authentication, Caching and Session providers are completely new, clean, dependency-free testable APIs that doesn't rely on and is devoid of ASP.NET's existing membership, caching or session provider models.

Custom authentication and authorization

The classes in ServiceStack have been designed to provide default behaviour out the box (convention over configuration). They are also highly customisable. Both the default BasicAuthProvider and CredentialsAuthProvider (which it extends) can be extended, and their behaviour overwritten. An example is below:

using ServiceStack;
using ServiceStack.Auth;

public class CustomCredentialsAuthProvider : CredentialsAuthProvider
{
    public override bool TryAuthenticate(IServiceBase authService, 
        string userName, string password)
    {
        //Add here your custom auth logic (database calls etc)
        //Return true if credentials are valid, otherwise false
    }

    public override void OnAuthenticated(IServiceBase authService, IAuthSession session, IAuthTokens tokens, Dictionary<string, string> authInfo)
    {
        //Fill IAuthSession with data you want to retrieve in the app eg:
        session.FirstName = "some_firstname_from_db";
        //...

        //Important: You need to save the session!
        authService.SaveSession(session, SessionExpiry);
    }
}

Then you need to register your custom credentials auth provider:

    //Register all Authentication methods you want to enable for this web app.
    Plugins.Add(new AuthFeature(() => new AuthUserSession(),
        new IAuthProvider[] {
        new CustomCredentialsAuthProvider(), //HTML Form post of User/Pass
        }
    ));

By default the AuthFeature plugin automatically registers the following (overrideable) Service Routes:

new AuthFeature = {
  ServiceRoutes = new Dictionary<Type, string[]> {
    { typeof(AuthService), new[]{"/auth", "/auth/{provider}"} },
    { typeof(AssignRolesService), new[]{"/assignroles"} },
    { typeof(UnAssignRolesService), new[]{"/unassignroles"} },
  }
};

e.g. The AuthService is registered at paths /auth and /auth/{provider} where the Provider maps to the IAuthProvider.Provider property of the registered AuthProviders. The urls for clients authenticating against the built-in AuthProviders are:

  • /auth/credentials - CredentialsAuthProvider
  • /auth/basic - BasicAuthProvider
  • /auth/twitter - TwitterAuthProvider
  • /auth/facebook - FacebookAuthProvider
  • /auth/yammer - YammerAuthProvider
  • /auth/googleopenid - GoogleOpenIdOAuthProvider
  • /auth/yahooopenid - YahooOpenIdOAuthProvider
  • /auth/myopenid - MyOpenIdOAuthProvider
  • /auth/openid - OpenIdOAuthProvider (Any Custom OpenId provider)
  • /auth/linkedin - LinkedInOAuth2Provider
  • /auth/googleoauth - GoogleOAuth2Provider

e.g. to Authenticate with your CustomCredentialsAuthProvider (which inherits from CredentialsAuthProvider) you would POST:

POST localhost:60339/auth/credentials?format=json

{
    "UserName": "admin",
    "Password": "test",
    "RememberMe": true
}

When the client now tries to authenticate with the request above and the auth succeeded, the client will retrieve some cookies with a session id which identify the client on each webservice call.

ServiceStack uses the CacheClient which was registered in the IoC container:

//Register a external dependency-free 
container.Register<ICacheClient>(new MemoryCacheClient() { 
    FlushOnDispose = false });

//Configure an alt. distributed persisted cache that survives AppDomain restarts. e.g Redis
//container.Register<IRedisClientsManager>(c => 
//    new PooledRedisClientManager("localhost:6379"));

Tip: If you've got multiple servers which run the same ServiceStack service, you can use Redis to share the sessions between these servers.


Please look at SocialBootstrapApi to get a full example.

Of course you can also implement your own - custom - authentication mechanism. You aren't forced to use the built-in ServiceStack auth mechanism.

The Authenticate attribute

But how does ServiceStack know, which service needs authentication? This happens with the AuthenticateAttribute.

You simply have to mark your request dto with this attribute:

//Authentication for all HTTP methods (GET, POST...) required
[Authenticate]
public class Secured
{
    public bool Test { get; set; }
}

Now this service can only be accessed if the client is authenticated:

public class SecuredService : Service
{
    public object Get(Secured request)
    {
        IOAuthSession session = this.GetSession();
        return new SecuredResponse() { Test = "You're" + session.FirstName };
    }

    public object Put(Secured request)
    {
        return new SecuredResponse() { Test = "Valid!" };
    }

    public object Post(Secured request)
    {
        return new SecuredResponse() { Test = "Valid!" };
    }

    public object Delete(Secured request)
    {
        return new SecuredResponse() { Test = "Valid!" };
    }
}

If you want, that authentication is only required for GET and PUT requests for example, you have to provide some extra parameters to the Authenticate attribute.

[Authenticate(ApplyTo.Get | ApplyTo.Put)] 

Of course Authenticate can also be placed on top of a service instead on top of a DTO, because it's a normal filter attribute.

The RequiredRole and RequiredPermission attributes

ServiceStack also includes a built-in permission based authorization mechanism. More details about how Roles and Permissions work is in this StackOverflow Answer.

Your request DTO can require specific permissions:

[Authenticate]
//All HTTP (GET, POST...) methods need "CanAccess"
[RequiredRole("Admin")]
[RequiredPermission("CanAccess")]
[RequiredPermission(ApplyTo.Put | ApplyTo.Post, "CanAdd")]
[RequiredPermission(ApplyTo.Delete, "AdminRights", "CanDelete")]
public class Secured
{
    public bool Test { get; set; }
} 

Now the client needs the permissions...

  • "CanAccess" to make a GET request
  • "CanAccess", "CanAdd" to make a PUT/POST request
  • "CanAccess", "AdminRights" and "CanDelete" to make a DELETE request

Normally ServiceStack calls the method bool HasPermission(string permission) in IAuthSession. This method checks if the list List<string> Permissions in IAuthSession contains the required permission.

IAuthSession is stored in a cache client as explained above

You can fill this list in the method OnAuthenticated you've overriden in the first part of this tutorial.

As with Authenticate, you can mark services (instead of DTO) with RequiredPermission attribute, too.

Enabling Authentication at different levels

Using the [Authenticate] Attribute

You can protect services by adding the [Authenticate] attribute on either the Action:

    class MyService : Service {
        [Authenticate] 
        public object Get(Protected request) { ... }
    }

The Request DTO

    [Authenticate] 
    class Protected { ... }

Or the service implementation

    [Authenticate] 
    class MyService : Service {
        public object Get(Protected request) { ... }
    }

Or by inheriting from a base class

    [Authenticate] 
    class MyServiceBase : Service { ... }

    class MyService : MyServiceBase {
        public object Get(Protected request) { ... }
    }

Using a Global Request Filter

Otherwise you can use a global Request Filter if you wanted to restrict all requests any other way, e.g something like:

    appHost.RequestFilters.Add((httpReq, httpResp, requestDto) =>
    {
        if (IsAProtectedPath(httpReq.PathInfo)) {
           new AuthenticateAttribute()
             .Execute(httpReq, httpResp, requestDto);
        }
    });

Extending User Auth tables

The different customization and extension points and strategies to extend the UserAuth tables with your own data are further explained in this StackOverflow answer.

Community Resources

Something went wrong with that request. Please try again.