IdentityServer4 角色+密码认证
IdentityServer:
using System; using FabricDemo.Consul; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Configuration; namespace FabricDemo.IdentityServer { public class Startup { IConfiguration Configuration { get; } public Startup(IConfiguration configuration) { Configuration = configuration; } // This method gets called by the runtime. Use this method to add services to the container. // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940 public void ConfigureServices(IServiceCollection services) { //services.AddControllers(); services.AddControllersWithViews().AddRazorRuntimeCompilation(); services.AddIdentityServer(options => { options.UserInteraction = new IdentityServer4.Configuration.UserInteractionOptions { //LoginUrl = "/Account/Login",//登录地址 //LogoutUrl = "/Account/Logout",//退出地址 //ConsentUrl = "/Account/Consent",//允许授权同意页面地址 //ErrorUrl = "/Account/Error", //错误页面地址 //LoginReturnUrlParameter = "ReturnUrl",//设置传递给登录页面的返回URL参数的名称。默认为returnUrl //LogoutIdParameter = "logoutId", //设置传递给注销页面的注销消息ID参数的名称。缺省为logoutId //ConsentReturnUrlParameter = "ReturnUrl", //设置传递给同意页面的返回URL参数的名称。默认为returnUrl //ErrorIdParameter = "errorId", //设置传递给错误页面的错误消息ID参数的名称。缺省为errorId //CustomRedirectReturnUrlParameter = "ReturnUrl", //设置从授权端点传递给自定义重定向的返回URL参数的名称。默认为returnUrl //CookieMessageThreshold = 5 //由于浏览器对Cookie的大小有限制,设置Cookies数量的限制,有效的保证了浏览器打开多个选项卡,一旦超出了Cookies限制就会清除以前的Cookies值 }; }) .AddDeveloperSigningCredential() .AddInMemoryIdentityResources(Config.GetIdentityResources()) .AddInMemoryApiResources(Config.GetApis()) .AddInMemoryClients(Config.GetClients()) .AddTestUsers(Config.GetUsers()) //.AddCustomAuthorizeRequestValidator<CustomAuthorizeRequestValidator>() .AddResourceOwnerValidator<CustomResourceOwnerPasswordValidator>() .AddProfileService<CustomProfileService>(); } //运行时将调用此方法。 使用此方法来配置HTTP请求管道。 public void Configure(IApplicationBuilder app, IWebHostEnvironment env, Microsoft.AspNetCore.Hosting.IApplicationLifetime lifetime) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseRouting(); // 如果要支持静态文件,请取消注释 app.UseStaticFiles(); #region Consul 服务注册 ServiceEntity serviceEntity = new ServiceEntity { IP = Configuration["Consul:ServiceIP"], //服务运行地址 Port = Convert.ToInt32(Configuration["Consul:ServicePort"]), //服务运行端口 ServiceName = Configuration["Consul:Name"], //服务标识,Ocelot中会用到 ConsulIP = Configuration["Consul:IP"], //Consul运行地址 ConsulPort = Convert.ToInt32(Configuration["Consul:Port"]) //Consul运行端口(默认8500) }; app.RegisterConsul(lifetime, serviceEntity); #endregion app.UseIdentityServer(); //app.UseAuthentication();//认证 app.UseAuthorization();//授权,.net core3.1要加上这句才行 //如果要添加基于MVC的UI,请取消注释 //app.UseMvcWithDefaultRoute(); app.UseEndpoints(endpoints => { endpoints.MapDefaultControllerRoute().RequireAuthorization(); }); } } }
using IdentityModel; using IdentityServer4; using IdentityServer4.Models; using IdentityServer4.Test; using System.Collections.Generic; using System.Security.Claims; namespace FabricDemo.IdentityServer { public static class Config { public static List<TestUser> GetUsers() { return new List<TestUser> { new TestUser { SubjectId = "1", Username = "alice", Password = "password", Claims = new List<Claim>(){ //new Claim(JwtClaimTypes.Role,"superadmin"), new Claim(JwtClaimTypes.Role,"admin"), new Claim(JwtClaimTypes.Profile,"custom.profile") } }, new TestUser { SubjectId = "2", Username = "bob", Password = "password", Claims = new List<Claim>(){new Claim(JwtClaimTypes.Role,"admin") } } }; } public static IEnumerable<IdentityResource> GetIdentityResources() { var customProfile = new IdentityResource { Name = "custom.profile", DisplayName = "Custom profile", UserClaims = new[] { "role" } }; return new IdentityResource[] { new IdentityResources.OpenId(), new IdentityResources.Profile(), new IdentityResource { Name = "Role", UserClaims = new List<string> { JwtClaimTypes.Role } }, customProfile }; } public static IEnumerable<ApiResource> GetApis() { return new List<ApiResource> { new ApiResource("UserService", "My API",new List<string>(){ JwtClaimTypes.Role}), new ApiResource("ProductService", "Product API",new List<string>(){ JwtClaimTypes.Role}), new ApiResource("IdentityServer", "IdentityServer",new List<string>(){ JwtClaimTypes.Role}), }; } public static IEnumerable<Client> GetClients() { return new List<Client> { new Client { ClientId = "client", // 没有交互式用户,请使用clientid / secret进行身份验证 AllowedGrantTypes = GrantTypes.ClientCredentials, //认证密钥 ClientSecrets = { new Secret("secret".Sha256()) }, //客户有权访问的范围 AllowedScopes = { "UserService" , IdentityServerConstants.StandardScopes.OpenId, IdentityServerConstants.StandardScopes.Profile, "IdentityServer" }, Claims=new List<Claim> { new Claim(JwtClaimTypes.Role,"admin") } }, new Client { ClientId = "ro.client", AllowedGrantTypes = GrantTypes.ResourceOwnerPassword, ClientSecrets = { new Secret("secret".Sha256()) }, AllowedScopes = { "UserService", "ProductService", "Role", IdentityServerConstants.StandardScopes.OpenId, IdentityServerConstants.StandardScopes.Profile, "custom.profile", "IdentityServer" } }, new Client { ClientId = "OcelotEditor", ClientName = "OcelotEditor", RequireConsent = false, AllowedGrantTypes = GrantTypes.HybridAndClientCredentials, ClientSecrets = { new Secret("49C1A7E1-0C79-4A89-A3D6-A37998FB86B0".Sha256()) }, RedirectUris = { "http://localhost:53000/signin-oidc" }, PostLogoutRedirectUris = { "https://localhost:53000/" }, AllowOfflineAccess = true, AllowedScopes = { "Role", IdentityServerConstants.StandardScopes.OpenId, IdentityServerConstants.StandardScopes.Profile, "custom.profile", "IdentityServer" }, }, new Client { ClientId = "UserService", ClientName = "UserService", RequireConsent = false, AllowedGrantTypes = GrantTypes.HybridAndClientCredentials, ClientSecrets = { new Secret("49C1A7E1-0C79-4A89-A3D6-A37998FB86B0".Sha256()) }, RedirectUris = { "http://localhost:61665/signin-oidc" }, PostLogoutRedirectUris = { "https://localhost:61665/" }, AllowOfflineAccess = true, AllowedScopes = { "Role", IdentityServerConstants.StandardScopes.OpenId, IdentityServerConstants.StandardScopes.Profile, "custom.profile", "IdentityServer", "UserService" }, AlwaysIncludeUserClaimsInIdToken=true } }; } } }
.net core 3 MVC:
using FabricDemo.Common; using FabricDemo.Consul; using FabricDemo.Models; using IdentityServer4; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.IdentityModel.Tokens; using System.IdentityModel.Tokens.Jwt; namespace FabricDemo.UserService { public class Startup { private IConfiguration Configuration; public Config Config; public Startup(IConfiguration configuration) { Configuration = configuration; Config = new Config(configuration); } // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddControllersWithViews(); ////使用IdentityServer4进行身份认证 //services.AddAuthentication(Config.AuthorityConfig.Scheme) // .AddJwtBearer(Config.AuthorityConfig.Scheme, options => //{ // options.Authority = Config.AuthorityConfig.Authority; // options.RequireHttpsMetadata = false; // options.Audience = Config.ServiceName; //}); //注入服務 // OrleanClusterDbConfig orleanClusterDbConfig = new OrleanClusterDbConfig(); services.AddConfiguration<OrleanClusterDbConfig>(Configuration,"ConnectingStrings:OrleanClusterDb"); //使用IdentityServer4进行身份认证 JwtSecurityTokenHandler.DefaultMapInboundClaims = false; services.AddAuthentication(options => { options.DefaultAuthenticateScheme = "Cookies"; options.DefaultChallengeScheme = "oidc"; }) .AddCookie("Cookies") .AddOpenIdConnect("oidc", options => { options.SignInScheme = "Cookies"; options.SaveTokens = true; options.Authority = Config.AuthorityConfig.Authority; options.RequireHttpsMetadata = false; options.ClientId = Config.ServiceName; options.ClientSecret = "49C1A7E1-0C79-4A89-A3D6-A37998FB86B0"; options.ResponseType = "code id_token"; options.GetClaimsFromUserInfoEndpoint = true; options.Scope.Add("Role"); options.Scope.Add(IdentityServerConstants.StandardScopes.OpenId); options.Scope.Add(IdentityServerConstants.StandardScopes.Profile); options.Scope.Add("custom.profile"); options.Scope.Add("IdentityServer"); options.Scope.Add("UserService"); //使用角色验证时,一定要加上下面这段,否则即使登录成功了,角色验证也不对,访问会被拒绝 options.TokenValidationParameters = new TokenValidationParameters { NameClaimType = "name", RoleClaimType = "role" }; }); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env, Microsoft.AspNetCore.Hosting.IApplicationLifetime lifetime) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseRouting(); #region Consul 服务注册 ServiceEntity serviceEntity = Config.ServiceEntity; app.RegisterConsul(lifetime, serviceEntity); #endregion app.UseAuthentication();//认证 app.UseAuthorization();//授权,.net core3.1要加上这句才行 app.UseEndpoints(endpoints => { endpoints.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); endpoints.MapAreaControllerRoute( name: "areas", "areas", pattern: "{area:exists}/{controller=Home}/{action=Index}/{id?}"); //endpoints.MapRazorPages(); }); } } }
浙公网安备 33010602011771号