Search code examples
authenticationasp.net-coreauthorizationidentityserver4

IdentityServer4 and integration with signinmanager


We are working on an application that uses IdentityServer4, a web api endpoint, a web administration front end, and a mobile application. We have the web application set up like this

public void ConfigureServices(IServiceCollection services) {
        services.AddMvc();

        JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();

        services
            .AddAuthentication(options => {
                options.DefaultScheme = "Cookies";
                options.DefaultChallengeScheme = "oidc";
            })
            .AddCookie("Cookies")
            .AddOpenIdConnect("oidc", options => {
                options.SignInScheme = "Cookies";

                options.Authority = "http://localhost:5000";
                options.RequireHttpsMetadata = false;

                options.ClientId = "mvc";
                options.ClientSecret = "secret";
                options.ResponseType = "code id_token";

                options.SaveTokens = true;
                options.GetClaimsFromUserInfoEndpoint = true;

                options.Scope.Add("api1");
                options.Scope.Add("offline_access");
            });
    }

This works and when we call into a controller that has an [Authorize] attribute on it, we get redirected, sign in, return to the calling site, and all is well.

Now we are trying to add authorization into the mix. I've seen the video where it is shown not to put authorization information into the token and I get that conceptually. But now I'd like to do something simple in the UI, like show or hide a link based on if the user is signed in or not. The default _LoginPartial page has something like this:

@inject SignInManager<User> SignInManager
@inject UserManager<User> UserManager

@if (SignInManager.IsSignedIn(User)) {
  User is signed in
} else {
  User is anonymous
}

In order to use SignInManager and UserManager, we'd have to set up the dependency service:

services.AddDbContext<Entities.ApplicationDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

services.AddIdentity<User, IdentityRole<long>>()
  .AddEntityFrameworkStores<ApplicationDbContext>()
  .AddDefaultTokenProviders();

But when I do that, it messes up the authorization attribute on the home controller.

How do I, using IdentityServer4, go about testing whether a user is logged in or not and access my role storage in the web application? I must be missing something that is allowing us to externally authenticate and then turn around and figure out what roles / claims the user is able to be in / use.


Solution

  • Use things like User.Identity.IsAuthenticated and User.Identity.IsInRole, etc. instead. While you can back IdentityServer with ASP.NET Identity, it's important to realize that your MVC app is using IdentityServer, not Identity, for authentication and authorization. As such, things like SignInManager.IsSignedIn won't work.