无法使用身份服务器访问客户端应用程序
Can't access client application using identity server
我正在尝试使用身份服务器对客户端 mvc 应用程序进行身份验证。
我的应用程序有身份服务器 mvc 应用程序,MVC 应用程序,API
我在客户端 MVC 应用程序中使用了 4 个范围(OpenId、电子邮件、个人资料、办公室——办公室是自定义声明类型)。
我正在使用此代码创建具有身份验证 mvc 应用程序的身份服务器。
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
身份服务器 - (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?}");
});
}
}
测试用户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, "AliceSmith@email.com"),
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, "BobSmith@email.com"),
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")
}
}
};
}
配置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[]
{
};
}
}
客户端 - Mvc 应用程序(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?}");
});
}
}
找到问题(这很难!)
代码工作正常。不起作用的部分是在 Consent
视图中显示范围。问题归结为这一行:
Views/Consent/Index.cshtml
<partial name="_ScopeListItem" model="@scope" />
这使用 ASP.NET 2.1 中引入的 Partial Tag Helper。
您在评论中链接的项目(您的项目)使用 ASP.NET 2.0,但是您从 IdentityServer 复制的 QuickStart UI
使用 ASP.NET Core 2.1,所以基本上,他们是不相容的。要修复,请为您的版本使用正确的标签助手或(我建议)升级到 ASP.NET Core 2.2。为此,您可以:
更改项目文件:
<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>
还有 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");
}
}
既然你喜欢它,我也建议升级 MVC(客户端)应用程序。我在您的 GitHub 存储库上发送了一个 PR,其中包含上述更改以及在您的用户登录后列出 scopes/claims 的视图。
我正在尝试使用身份服务器对客户端 mvc 应用程序进行身份验证。
我的应用程序有身份服务器 mvc 应用程序,MVC 应用程序,API
我在客户端 MVC 应用程序中使用了 4 个范围(OpenId、电子邮件、个人资料、办公室——办公室是自定义声明类型)。
我正在使用此代码创建具有身份验证 mvc 应用程序的身份服务器。
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
身份服务器 - (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?}");
});
}
}
测试用户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, "AliceSmith@email.com"),
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, "BobSmith@email.com"),
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")
}
}
};
}
配置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[]
{
};
}
}
客户端 - Mvc 应用程序(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?}");
});
}
}
找到问题(这很难!)
代码工作正常。不起作用的部分是在 Consent
视图中显示范围。问题归结为这一行:
Views/Consent/Index.cshtml
<partial name="_ScopeListItem" model="@scope" />
这使用 ASP.NET 2.1 中引入的 Partial Tag Helper。
您在评论中链接的项目(您的项目)使用 ASP.NET 2.0,但是您从 IdentityServer 复制的 QuickStart UI
使用 ASP.NET Core 2.1,所以基本上,他们是不相容的。要修复,请为您的版本使用正确的标签助手或(我建议)升级到 ASP.NET Core 2.2。为此,您可以:
更改项目文件:
<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>
还有 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");
}
}
既然你喜欢它,我也建议升级 MVC(客户端)应用程序。我在您的 GitHub 存储库上发送了一个 PR,其中包含上述更改以及在您的用户登录后列出 scopes/claims 的视图。