Use Existing Asp .Net Core Identity to validate SS API

We have an existing ASP .Net Core MVC Website, that uses the built in Identity API and SQL tables. We now need to add an API for other websites to share the data. I would ldeally like the API to be a separate program that just share a common DB, as each will run in a separate docker image.

We do not want to have to create another authentication system, as the current one is working well in our website, and most of the accounts will be common between both functions, website and API.

I thought I might find an Authentication provider in SS to use the .Net Core Identity API, but cannot seem to find one. Or am I missing something?

Has anyone achieved this? And if so, how?

Others may have their own solutions but I thought it was time we had an integrated Auth Provider built-in to enable integration with .NET Core Identity Auth which I’ve just added in this commit.

You can use the new NetCoreIdentityAuthProvider to add a custom ServiceStack AuthProvider which creates a ServiceStack Session using the currently authenticated .NET Core Identity with:

Plugins.Add(new AuthFeature(() => new AuthUserSession(), 
    new IAuthProvider[] {
        new NetCoreIdentityAuthProvider(AppSettings), 
    }));

By default it will map the default claims to their appropriate ServiceStack session property which you can further customize by specifying any custom claims and what ServiceStack Session property it should map to. E.g. if you had a custom claim to capture the company of the user you can could map it to ServiceStack Session with:

new NetCoreIdentityAuthProvider(AppSettings) {
    MapClaimsToSession = {
      [MyClaimTypes.Company] = nameof(AuthUserSession.Company)  
    },
}

It will also populate session.Roles if your Sign In added claims for the Users Roles (e.g. in ClaimTypes.Role), otherwise you can use the PopulateSessionFilter to further customize the ServiceStack Session that’s used for the request. e.g. the example below shows how to populate session.Roles from an EF managed role table using the Microsoft.AspNetCore.Identity.UserManager<TUser> API:

new NetCoreIdentityAuthProvider(AppSettings) {
    PopulateSessionFilter = (session, principal, req) => 
    {
        //Example of populating ServiceStack Session Roles for EF Identity DB
        var userManager = req.TryResolve<UserManager<ApplicationUser>>();
        var user = userManager.FindByIdAsync(session.Id).Result;
        var roles = userManager.GetRolesAsync(user).Result;
        session.Roles = roles.ToList();
    }
}, 

The new NetCoreIdentityAuthProvider is available from v5.4.1 that’s now available on MyGet.

1 Like

Many thanks for such a prompt reply, and I, and I guess many others, am extremely pleased you have decided to make an “official” AuthProvider for .Net Core Identity.

Please excuse my ignorance, but I have looked carefully at you code snippets above and also the source code in the commit, but I cannot see how this AuthProvider connects to the database containing the Identity data to validate logins from API Clients?

It doesn’t connect to the database directly itself, it provides an adapter which maps an Authenticated .NET Core Identity user to an authenticated ServiceStack User Session.

So you can continue to use your existing ASP.NET Core MVC Authentication and when you authenticate in MVC, the user will also be authenticated in ServiceStack. Essentially it uses the Authenticated .NET Core user as the source of the Authenticated ServiceStack User Session.

OK, I understand now. But I am trying to install your sample code in a test project, and it cannot find type NetCoreIdentityAuthProvider. I have downloaded the latest version of ServiceStack from MyGet. Do I need add a specific NuGet package to obtain this functionality?

Many thanks

I’ve downloaded the latest v5.4.1 on MyGet and can confirm that ServiceStack.dll it does contain NetCoreIdentityAuthProvider:

If you previously had ServiceStack v5.4.1 on MyGet installed you will need to clear your NuGet packages cache.

Many thanks after refreshing it finds the type. Will continue testing now.