0
votes

I'am try to authenticate client mvc application using identity server.

my application have Identity server mvc application , MVC application, API

I 'am used 4 scoped in client MVC application (OpenId,email,profile,office-- office is Custom claim type).

i'am use this code to create identity server with authenticate mvc application .

1 identity server run 

2 MVC application run 

3 Login link click using MVC application 

Image1

4 Login the identity server using TestUser details

Image2

5 after login success always display this screen (not show my all scope to check in client application)

Image3

Identity Server - (http://localhost:61632)

public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc();

            services.AddIdentityServer()
               .AddTestUsers(TestUsers.Users)
               .AddInMemoryClients(Config.GetClients())
               .AddInMemoryIdentityResources(Config.GetIdentityResources())
               .AddInMemoryApiResources(Config.GetApiResources());

        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseBrowserLink();
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
            }

            app.UseStaticFiles();

            app.UseIdentityServer();

            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");
            });
        }
    }

TestUser class

 public class TestUsers
    {
        public static List<TestUser> Users = new List<TestUser>
        {
            new TestUser{SubjectId = "818727", Username = "Kasunjith", Password = "kasunjith", 
                Claims = 
                {
                    new Claim("office_Id","23"),
                    new Claim(JwtClaimTypes.Name, "Alice Smith"),
                    new Claim(JwtClaimTypes.GivenName, "Alice"),
                    new Claim(JwtClaimTypes.FamilyName, "Smith"),
                    new Claim(JwtClaimTypes.Email, "[email protected]"),
                    new Claim(JwtClaimTypes.EmailVerified, "true", ClaimValueTypes.Boolean),
                    new Claim(JwtClaimTypes.WebSite, "http://alice.com"),
                    new Claim(JwtClaimTypes.Address, @"{ 'street_address': 'One Hacker Way', 'locality': 'Heidelberg', 'postal_code': 69118, 'country': 'Germany' }", IdentityServer4.IdentityServerConstants.ClaimValueTypes.Json)
                }
            },
            new TestUser{SubjectId = "88421113", Username = "bimal", Password = "bimal", 
                Claims = 
                {
                    new Claim("office_Id","24"),
                    new Claim(JwtClaimTypes.Name, "Bob Smith"),
                    new Claim(JwtClaimTypes.GivenName, "Bob"),
                    new Claim(JwtClaimTypes.FamilyName, "Smith"),
                    new Claim(JwtClaimTypes.Email, "[email protected]"),
                    new Claim(JwtClaimTypes.EmailVerified, "true", ClaimValueTypes.Boolean),
                    new Claim(JwtClaimTypes.WebSite, "http://bob.com"),
                    new Claim(JwtClaimTypes.Address, @"{ 'street_address': 'One Hacker Way', 'locality': 'Heidelberg', 'postal_code': 69118, 'country': 'Germany' }", IdentityServer4.IdentityServerConstants.ClaimValueTypes.Json),
                    new Claim("location", "somewhere")
                }
            }
        };
    }

Config class

 public class Config
    {
        public static IEnumerable<Client> GetClients()
        {
            return new Client[]
            {
                new Client
                {
                    ClientId ="mvc",
                    ClientName="MVC Demo",
                    AllowedGrantTypes = GrantTypes.Implicit,
                    RedirectUris ={ "http://localhost:62104/signin-oidc" },
                    AllowedScopes={ "openid","email", "profile","office"},
                    AllowRememberConsent = true,

                }

            };
        }

        public static IEnumerable<IdentityResource> GetIdentityResources()
        {
            return new IdentityResource[]
            {
                new IdentityResources.OpenId(),
                new IdentityResources.Email(),
                new IdentityResources.Profile(),
                new IdentityResource
                {
                    Name="office",
                    DisplayName ="office details",
                    UserClaims = {"office_Id"}
                }


            };
        }


        public static IEnumerable<ApiResource> GetApiResources()
        {
            return new ApiResource[]
            {

            };
        }
    }

Client - Mvc application ( http://localhost:62104)

public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc();

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

                 options.SignInScheme = "Cookies";
                 options.RequireHttpsMetadata = false;
                 options.Authority = "http://localhost:61632";
                 options.ClientId = "mvc";
                 options.ResponseType = "id_token";
                 //options.CallbackPath = new PathString("...")
                 //options.SignedOutCallbackPath = new PathString("...")
                 options.Scope.Add("openid");
                 options.Scope.Add("email");
                 options.Scope.Add("profile");
                 options.Scope.Add("office");




             });
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseBrowserLink();
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
            }

            app.UseStaticFiles();


            app.UseAuthentication();

            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");
            });
        }
    }
1
So: The user logs-in in your MVC app (using Identity Server). Then you want to call your API from your MVC app. Is that it? If that's the case, you have two options: Either create a second OAuth client for your MVC app so it can call the API OR use a custom grant type to exchange the user token with an API token. First case is the Client Credentials flow and the second you have to implement it: docs.identityserver.io/en/latest/topics/extension_grants.html - jpgrassi
Actually, I should have asked: What is the actual problem? You explained out well your code, but it's hard to understand the real issue. Is the login working at least? What is it you are trying to do and it's not working? - jpgrassi
i want to access my client application using identity server. In [Image3][3] always display this error.not load my all scope to unchek or check, - Kasun Bimal
Sorry but I'm unable to see the images. Make sure to upload them correctly because we can't see it. - jpgrassi
@jpgrassi or sry .now is it ok?? - Kasun Bimal

1 Answers

0
votes

Found the issue (this was hard!)

The code works just fine. The part that does not work is displaying the scopes in the Consent View. The problem boils down to this line:

Views/Consent/Index.cshtml

<partial name="_ScopeListItem" model="@scope" />

This uses the Partial Tag Helper, introduced in ASP.NET 2.1.

The project you linked in the comments (your project) uses ASP.NET 2.0, but the QuickStart UI you copied from IdentityServer uses ASP.NET Core 2.1 so basically, they are incompatible. To fix, either use the proper Tag helper for your version or (I recommend) upgrade to ASP.NET Core 2.2. For that you can:

Change the project file:

<Project Sdk="Microsoft.NET.Sdk.Web">

  <!-- Upgrade the project to .NET Core 2.2-->
  <PropertyGroup>
    <TargetFramework>netcoreapp2.2</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="IdentityServer4" Version="2.3.2" />

    <!-- Change the ASP.NET Core from All to App. -->
    <PackageReference Include="Microsoft.AspNetCore.App" />
  </ItemGroup>

  <ItemGroup>
    <DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.2" />
  </ItemGroup>

</Project>

And the Startup.cs

public IConfiguration Configuration { get; }
public IHostingEnvironment Environment { get; }

public Startup(IConfiguration configuration, IHostingEnvironment environment)
{
    Configuration = configuration;
    Environment = environment;
}

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc().SetCompatibilityVersion(Microsoft.AspNetCore.Mvc.CompatibilityVersion.Version_2_1);

    var builder = services.AddIdentityServer()
       .AddTestUsers(TestUsers.Users)
       .AddInMemoryClients(Config.GetClients())
       .AddInMemoryIdentityResources(Config.GetIdentityResources())
       .AddInMemoryApiResources(Config.GetApiResources());

    // without this you can't sign jwt tokens in dev. still need to configure for prod.
    if (Environment.IsDevelopment())
    {
        builder.AddDeveloperSigningCredential();
    }
    else
    {
        throw new Exception("need to configure key material");
    }

}

Since you are into it, I'd also suggest upgrading the MVC (client) app as well. I sent a PR on your GitHub repo that has the changes mentioned above plus a view to listing the scopes/claims after your user is logged in.