Vue 使用的是D2admin: https://doc.d2admin.fairyever.com/zh/
Github地址:https://github.com/Fengddd/PermissionAdmin.git
Net Core的环境:Webapi 使用的是:NET Core SDK2.1 IdentityServer和Ocelot:NET Core SDK2.2
Github地址:https://github.com/Fengddd/IdentityServerOcelotDemo.git
我也是在初学阶段,所以有些地方可能描述的不是很清楚,可以下载源码查看,也可能大家一起交流,学习
public static IEnumerable<IdentityResource> GetIdentityResources()
{
return new IdentityResource[]
{
new IdentityResources.OpenId(),
new IdentityResources.Profile(),
new IdentityResource("delimitClaim","delimitClaim",new List<string>(){ "role", "name"}), //在Claims添加role 和 name信息
};
}
public static IEnumerable<ApiResource> GetApiResource()
{
return new List<ApiResource>
{
new ApiResource("identityServerApi", "identityServerApi"),
};
}
public static IEnumerable<Client> GetClients()
{
new Client
{
ClientId = "js", //客户端Id
ClientName = "JavaScript Client", //客户端名称
AllowedGrantTypes = GrantTypes.Code, //授权模式
//AllowedGrantTypes = GrantTypes.Implicit,
RequirePkce = true,
RequireClientSecret = false,
RequireConsent = false, //禁用 consent 页面确认
AllowAccessTokensViaBrowser = true,
AlwaysIncludeUserClaimsInIdToken = true,
RedirectUris =
{
"http://localhost:8080/#/IdentityServerCallBack", //登陆后回调页面
"http://localhost:8080/#/IdentityServerRefreshToken" //刷新Token的页面
},
PostLogoutRedirectUris = { "http://localhost:8080/#/IdentityServerClient" },//注销退出后跳转的页面(登录页)
AllowedCorsOrigins = { "http://localhost:8080" }, //跨域
AccessTokenLifetime = 60, //AccessToken 的有效时间
AllowedScopes =
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
"identityServerApi", //授权的Scopes
"delimitClaim" //Claims 信息
},
AllowOfflineAccess = true,
}
}
有时我们需要自定义验证以及自定义一些Claim的信息,所以需要实现 IProfileService 接口
public virtual Task GetProfileDataAsync(ProfileDataRequestContext context)
{
context.LogProfileRequest(Logger);
//判断是否有请求Claim信息
if (context.RequestedClaimTypes.Any())
{
var userClaims = new List<Claim>
{
new Claim("demo1", "测试1"),
new Claim("demo2", "测试2"),
};
List<TestUser> userList = new List<TestUser>()
{
new TestUser(){SubjectId = "cfac01a9-ba15-4678-bccb-cc22d7896362",Password = "123456",Username="李锋",Claims = userClaims},
new TestUser(){SubjectId = "cfac01a9-ba15-4678-bccb-cc22d7855555",Password = "123456",Username="张三"},
};
TestUserStore userStore = new TestUserStore(userList);
//根据用户唯一标识查找用户信息
var user = userStore.FindBySubjectId(context.Subject.GetSubjectId());
if (user != null)
{
//调用此方法以后内部会进行过滤,只将用户请求的Claim加入到 context.IssuedClaims 集合中 这样我们的请求方便能正常获取到所需Claim
context.AddRequestedClaims(user.Claims);
}
//context.IssuedClaims=userClaims;
}
context.LogIssuedClaims(Logger);
return Task.CompletedTask;
}
/// <summary>
/// 验证用户是否有效 例如:token创建或者验证
/// </summary>
/// <param name="context">The context.</param>
/// <returns></returns>
public virtual Task IsActiveAsync(IsActiveContext context)
{
Logger.LogDebug("IsActive called from: {caller}", context.Caller);
var userClaims = new List<Claim>
{
new Claim("demo1", "测试1"),
new Claim("demo2", "测试2"),
};
List<TestUser> userList = new List<TestUser>()
{
new TestUser(){SubjectId = "cfac01a9-ba15-4678-bccb-cc22d7896362",Password = "123456",Username="李锋",Claims = userClaims},
new TestUser(){SubjectId = "cfac01a9-ba15-4678-bccb-cc22d7855555",Password = "123456",Username="张三"},
};
TestUserStore userStore = new TestUserStore(userList);
var user = userStore.FindBySubjectId(context.Subject.GetSubjectId());
context.IsActive = user?.IsActive == true;
return Task.CompletedTask;
}
其中关于Claims的地方这里做测试所以直接实例出来的数据,这里可以通过读取数据库进行验证,以及添加Claims的信息
在Startup 的ConfigureServices 注入IdentityServer信息 ,Configure下注册UseIdentityServer中间件
services.AddIdentityServer()
.AddDeveloperSigningCredential()
.AddInMemoryIdentityResources(IdentityConfig.GetIdentityResources())
.AddInMemoryApiResources(IdentityConfig.GetApiResource())
.AddInMemoryClients(IdentityConfig.GetClients())
//.AddTestUsers(IdentityConfig.GetUsers().ToList())
.AddProfileService<IdentityProfileService>(); //使用的是Code模式,使用自定义Claims信息
//.AddResourceOwnerValidator<IdentityResourceOwnerPasswordValidator>();
app.UseIdentityServer();
然后找到QuickStart中的登录方法,这里修改为从数据库读取验证用户信息
"ReRoutes": [
{
"DownstreamPathTemplate": "/api/{url}",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 44375
}
],
"UpstreamPathTemplate": "/api/{url}",
"UpstreamHttpMethod": [ "Get", "Post" ],
"Priority": 2,
"AuthenticationOptions": {
"AuthenticationProviderKey": "IdentityServerKey",
"AllowScopes": [ "identityServerApi", "delimitClaim" ]
},
"RateLimitOptions": {
"ClientWhiteList": [ //白名单
],
"EnableRateLimiting": true, //启用限流
"Period": "1m",
"PeriodTimespan": 30,
"Limit": 5
},
"QoSOptions": {
"ExceptionsAllowedBeforeBreaking": 3,
"DurationOfBreak": 3000,
"TimeoutValue": 5000
}
]
}
services.AddAuthentication()
.AddIdentityServerAuthentication("IdentityServerKey", options =>
{
options.Authority = "http://localhost:17491";
options.ApiName = "identityServerApi";
options.SupportedTokens = IdentityServer4.AccessTokenValidation.SupportedTokens.Both;
options.RequireHttpsMetadata = false;
});
services.AddOcelot()
.AddConsul()
.AddPolly();
//配置跨域处理
services.AddCors(options =>
{
options.AddPolicy("any", builder =>
{
builder.AllowAnyOrigin() //允许任何来源的主机访问
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials();//指定处理cookie
});
});
//配置Cors
app.UseCors("any");
app.UseAuthentication();
Program中添加
public static IWebHostBuilder CreateWebHostBuilder(string[] args)
{
return WebHost.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((hostingContext, config) =>
{
config
.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath)
.AddOcelot(hostingContext.HostingEnvironment) //ocelot合并配置文件,不能出现同样的一个端口,多个路由
.AddEnvironmentVariables();
})
.UseStartup<Startup>();
}
Edison Zhou:https://www.cnblogs.com/edisonchou/p/integration_authentication-authorization_service_foundation.html IdentityServer4和ocelot
晓晨Master:https://www.cnblogs.com/stulzq/category/1060023.html IdentityServer4
solenovex :https://www.cnblogs.com/cgzl/tag/identity%20server%204/ IdentityServer4 bibi上还有IdentityServer4视频喔
灭蒙鸟:https://www.jianshu.com/p/fde63052a3a5 入门教程:JS认证和WebAPI
.Net框架学苑:https://www.cnblogs.com/letyouknowdotnet/category/1481970.html ocelot 一系列教程
使用.Net Core + Vue + IdentityServer4 + Ocelot 实现一个简单的DEMO +源码
原文:https://www.cnblogs.com/lifeng618/p/11405281.html