Skip to content
Demis Bellot edited this page Feb 2, 2017 · 38 revisions

This page has moved to docs.servicestack.net/sessions


The AuthFeature (plugin) already enables the SessionFeature, but if you want to make use of sessions and don't want to enable the built-in Authentication, you will need to register it manually in your AppHost with:

public override void Configure(Container container)
{
    Plugins.Add(new SessionFeature());
}

Cookie Session Ids

When the SessionFeature is enabled, a Global RequestFilter is added to ServiceStack to ensure that all requests have a Temporary ss-id and a Permanent ss-pid session cookies set. These Session Cookies contain a unique Random Base64-encoded Id. The ss-opt cookie stores the users preference on whether they want their current session to be temporary (ss-opt=temp) or permanent (ss-opt=perm) - i.e. to RememberMe or not - The Default is Temporary.

Permanent and Temporary Session Ids

The Permanent session cookie ss-pid is always created even if ss-opt is Temporary - this allows you to link and track subsequent requests together which can be helpful for user request analyzing. In contrast the temporary Session Id ss-id uses a temporary cookie that does not persist across a users browser sessions.

If you're interested in the implementation, all the source code for ServiceStack's Sessions are kept in the ISession, SessionFeature, SessionFactory, SessionExtensions and ServiceExtensions classes.

Can be used with any ICacheClient

ServiceStack's implementation of Sessions are clean, in that they work with all of ServiceStack's Caching Providers and are simply pointers to POCOs in your Cache. An example of getting ServiceStack to use an in-memory cache:

container.Register<ICacheClient>(new MemoryCacheClient());

Formatting of Keys used in Cache Providers

For typed or Custom AuthSession the key is:

urn:iauthsession:{sessionId}

When using un-typed Session Bag the key is:

sess:{sessionId}:{key}

The general recommendation is to use typed sessions, which will give you type-safety benefits as well as being able to fetch your entire users session with a single cache call. If you use the dynamic/session bag then it will be a network call for each key accessed - although as caches are designed for fast-access, this isn't too much of a concern.

Using Typed Sessions in ServiceStack

An example of using Typed Sessions is in the Social Bootstrap Api demo where a CustomUserSession is defined as:

[DataContract]
public class CustomUserSession : AuthUserSession 
{
    [DataMember]
    public string CustomId { get; set; }
}

By inheriting AuthUserSession you're able to keep all the users session together in 1 POCO, which allows you to access everything in 1 cache read or write.

When inheriting from AuthUserSession you will need to annotate your properties with [DataMember] as AuthUserSession is a DataContract class.

To tell ServiceStack to use your Custom Typed Session instead, register it in the AuthFeature plugin:

Plugins.Add(new AuthFeature(() => new CustomUserSession(), ...));

Session events

Inheriting from the AuthUserSession also lets you add custom logic for different events in the User Session life-cycle:

virtual void OnCreated(IRequest httpReq) {}
virtual void OnRegistered(IServiceBase registrationService) {}
virtual void OnAuthenticated(IServiceBase authService, IAuthSession session, 
    IAuthTokens tokens, Dictionary<string, string> authInfo) {}
virtual void OnLogout(IServiceBase authService) {}

Auth Events

The same authentication hooks that are available in the Custom UserSession above are also available in IAuthEvents API:

public interface IAuthEvents
{
    void OnRegistered(IRequest req, IAuthSession session, IServiceBase registerService);
    void OnAuthenticated(IRequest req, IAuthSession session, IServiceBase authService, 
        IAuthTokens tokens, Dictionary<string, string> authInfo);
    void OnLogout(IRequest req, IAuthSession session, IServiceBase authService);
    void OnCreated(IRequest req, IAuthSession session);
}

The new AuthEvents API provide a loose-typed way where plugins can tap into the same hooks by registering it with AuthFeature.AuthEvents, e.g:

public class WebSudoFeature : IPlugin, IAuthEvents
{
    public void Register(IAppHost appHost)
    {
        ...
        var authFeature = appHost.GetPlugin<AuthFeature>();
        authFeature.AuthEvents.Add(this);
    }

    // Add implementations of all `IAuthEvents` handlers
    public void OnCreated(IRequest httpReq, IAuthSession session) { ... }
}

An alternative way for accessing IAuthEvents is to register it like a normal dependency, e.g:

container.RegisterAs<LogAuthEvents,IAuthEvents>();

To simplify custom implementations you can inherit from the empty concrete AuthEvents and choose to only implement the callbacks you're interested in, e.g:

public class LogAuthEvents : AuthEvents
{
    public static ILog Log = LogManager.GetLogger(typeof(LogAuthEvents));

    public override void OnLogout(IRequest httpReq, IAuthSession session, IServiceBase authService) 
    {
        Log.DebugFormat("User #{0} {1} has logged out", session.UserAuthId, session.UserName);
    }
}

Accessing Typed Session

You can access your custom UserAuth session inside your service using the SesssionAs<T>() extension method, e.g:

public abstract class MyService : Service 
{
    public object Get(MyRequest request)
    {
        var typedSession = this.SessionAs<CustomUserSession>();
    }
}

Adding a Convenience wrapper

To provide a typed, Convenient API for your service you can add the following to a base class, here's SocialBootstrapApi's AppServiceBase example:

public abstract class AppServiceBase : Service {
    private CustomUserSession userSession;
    protected CustomUserSession UserSession {
        get {
            return base.SessionAs<CustomUserSession>();
        }
    }
}

This will then enable you to access your users Session in your ServiceStack services with base.UserSession.

Sharing ServiceStack's Typed Sessions in MVC and ASP.NET

ASP.NET's Session Provider model still maintains its old legacy .NET 1.0 roots with it's heavy XML-encumbered config model, it's coupled and un-testable API, and its degrading performance limitations by design makes it difficult for any web service framework to share the same User Sessions with the base ASP.NET Web Forms or MVC web host.

ServiceStack gets around these limitations by providing its own de-coupled, testable and dependency-free ICacheClient and ISession APIs - which all work simply together as they're just plain Guid Session Keys stored in Caches pointing to POCOs.

The method SessionFeature.GetSessionKey allows you to get a Session Key for a current request if you are trying to access it in ASP.NET Web Forms or MVC web host. Using a Session Key you can have a full control over Session object:

// CacheClient is instance of ICacheClient

var sessionKey = SessionFeature.GetSessionKey();

// geting an existing User Session or create a new one 
var userSession = SessionFeature.GetOrCreateSession<AuthUserSession>(CacheClient); 
// or SessionFeature.GetOrCreateSession<CustomUserSession>(CacheClient); 

Saving in Service

As a typed session is just a disconnected POCO, it needs to explicitly saved to be persisted - which you can do with the base.SaveSession() Extension method.

public object Any(Request request)
{
    var session = base.SessionAs<AuthUserSession>();

    // modify session

    base.Request.SaveSession(session);
}

Saving outside a Service

If your logic is outside a ServiceStack service you can save your typed session by getting access to the ServiceStack IRequest which you can create from ASP.NET Request objects:

IHttpRequest httpReq = aspCtx.ToRequest(); //HttpContext
IHttpRequest httpReq = aspReq.ToRequest(); //MVC HttpRequestBase
IHttpRequest httpReq = listenerCtx.ToRequest(); //HttpListenerContext

//In ASP.NET hosts via the singleton
IHttpRequest httpReq = HostContext.AppHost.TryGetCurrentRequest(); 

Once you have access to the current IRequest you can save your typed session using the SaveSession() extension method:

httpReq.SaveSession(session);

This API is also available in MVC Controllers that inherit ServiceStackController or ASP.NET Pages that inherit ServiceStackPage:

base.SaveSession(session);

Typed Sessions in MVC

To make use of it in MVC, you effectively do the same thing, although this time you can simply inherit the existing ServiceStackController which has the above templated code in a generic MVC Controller Template:

public class ControllerBase : ServiceStackController<CustomUserSession> {}

From there it's just a basic property which you can use in your Controller or assign to your views like this:

public partial class HomeController : ControllerBase 
{
    public virtual ActionResult Index() 
    {
        ViewBag.Message = "MVC + ServiceStack PowerPack!";
        ViewBag.UserSession = base.UserSession;
        return View();
    }   
}

Typed Sessions in ASP.NET Web Forms

It's the same thing in ASP.NET Web Forms although this comes in the form of a base ASP.NET Web Page which you get for free when you install ServiceStack via the ServiceStack.Host.AspNet NuGet package.

Using Dynamic / Untyped Sessions in ServiceStack

You can access the dynamic UserSession Bag in ServiceStack services via the base.Session property already built-in ServiceStack's ServiceBase base class, e.g:

base.SessionBag["cart"] = new Cart { ... };
var cart = base.SessionBag.Get<Cart>("cart");

Use HTTP Headers to Send Session Cookies

You can now make a Session-enabled request with HTTP Headers instead of Cookies. The Session HTTP Headers have a X- prefix before the Session Id, i.e: X-ss-id, X-ss-pid and X-ss-opts.

Inspecting persisted User Sessions

ServiceStack Sessions are just serialized POCO's stored in the Registered ICacheClient at the following key:

urn:iauthsession:{SessionId}

Where {SessionId} is either the users ss-id or ss-pid cookie depending on whether the user was authenticated with RememberMe=true which instructs ServiceStack to save the session against the ss-pid permanent cookie - this preference is stored in the ss-opt=perm cookie.

Since they're just plain POCO's stored at a predictable key format, we can easily iterate through all user sessions by using the ICacheClient API's directly, e.g:

var sessionPattern = IdUtils.CreateUrn<IAuthSession>(""); //= urn:iauthsession:
var sessionKeys = Cache.GetKeysStartingWith(sessionPattern).ToList();

var allSessions = Cache.GetAll<IAuthSession>(sessionKeys);

Community Resources



  1. Getting Started

    1. Creating your first project
    2. Create Service from scratch
    3. Your first webservice explained
    4. Example Projects Overview
    5. Learning Resources
  2. Designing APIs

    1. ServiceStack API Design
    2. Designing a REST-ful service with ServiceStack
    3. Simple Customer REST Example
    4. How to design a Message-Based API
    5. Software complexity and role of DTOs
  3. Reference

    1. Order of Operations
    2. The IoC container
    3. Configuration and AppSettings
    4. Metadata page
    5. Rest, SOAP & default endpoints
    6. SOAP support
    7. Routing
    8. Service return types
    9. Customize HTTP Responses
    10. Customize JSON Responses
    11. Plugins
    12. Validation
    13. Error Handling
    14. Security
    15. Debugging
    16. JavaScript Client Library (ss-utils.js)
  4. Clients

    1. Overview
    2. C#/.NET client
      1. .NET Core Clients
    3. Add ServiceStack Reference
      1. C# Add Reference
      2. F# Add Reference
      3. VB.NET Add Reference
      4. Swift Add Reference
      5. Java Add Reference
    4. Silverlight client
    5. JavaScript client
      1. Add TypeScript Reference
    6. Dart Client
    7. MQ Clients
  5. Formats

    1. Overview
    2. JSON/JSV and XML
    3. HTML5 Report Format
    4. CSV Format
    5. MessagePack Format
    6. ProtoBuf Format
  6. View Engines 4. Razor & Markdown Razor

    1. Markdown Razor
  7. Hosts

    1. IIS
    2. Self-hosting
    3. Messaging
    4. Mono
  8. Security

    1. Authentication
    2. Sessions
    3. Restricting Services
    4. Encrypted Messaging
  9. Advanced

    1. Configuration options
    2. Access HTTP specific features in services
    3. Logging
    4. Serialization/deserialization
    5. Request/response filters
    6. Filter attributes
    7. Concurrency Model
    8. Built-in profiling
    9. Form Hijacking Prevention
    10. Auto-Mapping
    11. HTTP Utils
    12. Dump Utils
    13. Virtual File System
    14. Config API
    15. Physical Project Structure
    16. Modularizing Services
    17. MVC Integration
    18. ServiceStack Integration
    19. Embedded Native Desktop Apps
    20. Auto Batched Requests
    21. Versioning
    22. Multitenancy
  10. Caching

  11. Caching Providers

  12. HTTP Caching 1. CacheResponse Attribute 2. Cache Aware Clients

  13. Auto Query

  14. Overview

  15. Why Not OData

  16. AutoQuery RDBMS

  17. AutoQuery Data 1. AutoQuery Memory 2. AutoQuery Service 3. AutoQuery DynamoDB

  18. Server Events

    1. Overview
    2. JavaScript Client
    3. C# Server Events Client
    4. Redis Server Events
  19. Service Gateway

    1. Overview
    2. Service Discovery
  20. Encrypted Messaging

    1. Overview
    2. Encrypted Client
  21. Plugins

    1. Auto Query
    2. Server Sent Events
    3. Swagger API
    4. Postman
    5. Request logger
    6. Sitemaps
    7. Cancellable Requests
    8. CorsFeature
  22. Tests

    1. Testing
    2. HowTo write unit/integration tests
  23. ServiceStackVS

    1. Install ServiceStackVS
    2. Add ServiceStack Reference
    3. TypeScript React Template
    4. React, Redux Chat App
    5. AngularJS App Template
    6. React Desktop Apps
  24. Other Languages

    1. FSharp
      1. Add ServiceStack Reference
    2. VB.NET
      1. Add ServiceStack Reference
    3. Swift
    4. Swift Add Reference
    5. Java
      1. Add ServiceStack Reference
      2. Android Studio & IntelliJ
      3. Eclipse
  25. Amazon Web Services

  26. ServiceStack.Aws

  27. PocoDynamo

  28. AWS Live Demos

  29. Getting Started with AWS

  30. Deployment

    1. Deploy Multiple Sites to single AWS Instance
      1. Simple Deployments to AWS with WebDeploy
    2. Advanced Deployments with OctopusDeploy
  31. Install 3rd Party Products

    1. Redis on Windows
    2. RabbitMQ on Windows
  32. Use Cases

    1. Single Page Apps
    2. HTML, CSS and JS Minifiers
    3. Azure
    4. Connecting to Azure Redis via SSL
    5. Logging
    6. Bundling and Minification
    7. NHibernate
  33. Performance

    1. Real world performance
  34. Other Products

    1. ServiceStack.Redis
    2. ServiceStack.OrmLite
    3. ServiceStack.Text
  35. Future

    1. Roadmap
Clone this wiki locally