在项目中自定义集成IdentityService4
OAuth2.0协议
在开始之前呢,需要我们对一些认证授权协议有一定的了解。
OAuth 2.0 的一个简单解释
http://www.ruanyifeng.com/blog/2019/04/oauth_design.html
理解 OAuth 2.0
https://www.ruanyifeng.com/blog/2014/05/oauth_2_0.html
GitHub OAuth 第三方登录示例教程
http://www.ruanyifeng.com/blog/2019/04/github-oauth.html
IdentityService4 配置说明
当然,前提是我希望你已经对一些官方示例进行了实践,如果没有,下面链接中有中文的案例演示
http://www.identityserver.com.cn/
在官方文档中我们可以在导航栏看到一些配置项,其实常用的只有Client这一项
https://identityserver4.readthedocs.io/en/latest/index.html
开始操作
先简单概述一下我们需要做的事情:
1、存储IdentityService4配置信息
2、存储用户数据 (采用ASP.NET Core Identity)
针对上面两项,官方都有实现,都有针对各自的案例,我们只需要做一个简单的集合,按需集合进项目中。
建立一个空web项目
.NET Core 版本不做要求 3.1、 5.0、 6.0 都可以实现 ,需要注意的是6.0版本的IdentityService4已经没有升级了,有一些Nuget包可能是过时的,当出现时,根据提示改为自己需要的版本即可。
我个人喜欢建立MVC,因为方便,中间件都有,懒得一个个引用了
添加所需NuGet包
Startup.cs文件中注册Identity
// 配置cookie策略 (此配置下方会讲解)
builder.Services.Configure<CookiePolicyOptions>(options =>
{
//让IdentityService4框架在http的情况下可以写入cookie
options.MinimumSameSitePolicy = Microsoft.AspNetCore.Http.SameSiteMode.Lax;
});
//注册Identity
//IdentityDB迁移命令
//Add-Migration InitialIAspNetIdentityConfigurationDbMigration -c ApplicationDbContext -o Data/Migrations/AspNetIdentity
builder.Services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(configuration.GetConnectionString("IdentityDb"), sql => sql.MigrationsAssembly(migrationsAssembly)));
builder.Services.AddIdentity<ApplicationUser, ApplicationRole>(options =>
{
//密码配置
options.Password.RequireNonAlphanumeric = false;
options.Password.RequireDigit = false;
options.Password.RequiredLength = 6;
options.Password.RequireUppercase = false;
})
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
用的是SqlServer,如若使用MySQL替换Nuget包即可,Oracle有点特殊,自行探索,太麻烦就不说了
ApplicationUser 、ApplicationRole 是我自定义扩展Identity的用户和角色,这我就不多说了,用过Identity的都知道
Startup.cs文件中注册IdentityService4
IdentityService4用了两个DbContext,一个存储配置信息,一个存储操作信息
//注册ID4
builder.Services.AddIdentityServer()
.AddConfigurationStore(options =>
{
//Add-Migration InitialIdentityServerConfigurationDbMigration -c ConfigurationDbContext -o Data/Migrations/IdentityServer/ConfigurationDb
options.ConfigureDbContext = b => b.UseSqlServer(configuration.GetConnectionString("IdentityDb"), sql => sql.MigrationsAssembly(migrationsAssembly));
})
.AddOperationalStore(options =>
{
//Add-Migration InitialIdentityServerPersistedGrantDbMigration -c PersistedGrantDbContext -o Data/Migrations/IdentityServer/PersistedGrantDb
options.ConfigureDbContext = b => b.UseSqlServer(configuration.GetConnectionString("IdentityDb"), sql => sql.MigrationsAssembly(migrationsAssembly));
})
.AddAspNetIdentity<ApplicationUser>()
.AddDeveloperSigningCredential(true);
在授权中间件前,引入IdentityService4中间件
数据库迁移
此处需要将Identity的Dbcontext上下文,和IdentityService4的两个DbContext上下文 迁移进数据库中,迁移命令上面已有,执行即可。
//IdentityDB迁移命令
//Add-Migration InitialIAspNetIdentityConfigurationDbMigration -c ApplicationDbContext -o Data/Migrations/AspNetIdentity
//Add-Migration InitialIdentityServerConfigurationDbMigration -c ConfigurationDbContext -o Data/Migrations/IdentityServer/ConfigurationDb
//Add-Migration InitialIdentityServerPersistedGrantDbMigration -c PersistedGrantDbContext -o Data/Migrations/IdentityServer/PersistedGrantDb
添加自定义所需的页面(登录、注册等)
这些页面来自官方免费的管理UI、或者Identity,代码在源码中,自行拷贝即可
如需其他功能页面,按需从官方Copy即可
添加测试种子数据
此处代码太多,自行去源码查看,讲一下原理:
将IdentityService的Client、Scope等配置信息存储到数据库中 , 初始化用户、角色 信息
编译运行,不报错,成功!
校验一下
在当前项目新增一个Api控制器,返回当前Token所包含的声明信息
注意红色部分,需要我们添加jwt认证
添加Jwt身份认证
我们在上面注册服务时,IS4默认使用的是Cookie认证
所以在添加JwtBearer认证
string identityServerUrl = configuration["Perfect:Identity:Url"]; //当前项目地址
//添加jwt认证方案
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, options =>
{
options.Authority = identityServerUrl;
options.RequireHttpsMetadata = false;
options.TokenValidationParameters.ValidateAudience = false;
options.TokenValidationParameters.ValidateLifetime = true;
options.TokenValidationParameters.ClockSkew = TimeSpan.Zero;
});
配置swagger认证
先添加一个过滤器
public class SecurityRequirementsOperationFilter : IOperationFilter
{
/// <summary>
/// Add Security Definitions and Requirements
/// https://github.com/domaindrivendev/Swashbuckle.AspNetCore#add-security-definitions-and-requirements
/// </summary>
public void Apply(OpenApiOperation operation, OperationFilterContext context)
{
bool hasAuthorize = context.MethodInfo.DeclaringType?.GetCustomAttributes(true).OfType<AuthorizeAttribute>().Any() == true || context.MethodInfo.GetCustomAttributes(true).OfType<AuthorizeAttribute>().Any();
bool hasAllowAnonymous = context.MethodInfo.DeclaringType?.GetCustomAttributes(true).OfType<AllowAnonymousAttribute>().Any() == true || context.MethodInfo.GetCustomAttributes(true).OfType<AllowAnonymousAttribute>().Any();
if (hasAuthorize && !hasAllowAnonymous)
{
operation.Responses.Add("401", new OpenApiResponse { Description = "Unauthorized" });
operation.Responses.Add("403", new OpenApiResponse { Description = "Forbidden" });
OpenApiSecurityScheme oAuthScheme = new OpenApiSecurityScheme()
{
Reference = new OpenApiReference() { Type = ReferenceType.SecurityScheme, Id = "oauth2" }
};
operation.Security = new List<OpenApiSecurityRequirement>
{
new OpenApiSecurityRequirement
{
[oAuthScheme] =new []{ "Perfect.Api" }
}
};
}
}
}
在Startup中注册,客户端ID、和客户端密钥 来自步骤 “添加测试种子数据” 中
//configuration["xx"]是来自配置文件的取值
//添加Swagger文档
services.AddSwaggerGen(c =>
{
c.SwaggerDoc(configuration["Perfect:Swagger:Name"], new OpenApiInfo
{
Title = configuration["Perfect:Swagger:Title"],
Version = configuration["Perfect:Swagger:Version"],
Description = configuration["Perfect:Swagger:Description"],
Contact = new OpenApiContact
{
Name = configuration["Perfect:Swagger:Contact:Name"],
Email = configuration["Perfect:Swagger:Contact:Email"]
}
});
c.OperationFilter<SecurityRequirementsOperationFilter>();
c.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme
{
Type = SecuritySchemeType.OAuth2,
Flows = new OpenApiOAuthFlows
{
AuthorizationCode = new OpenApiOAuthFlow
{
AuthorizationUrl = new Uri($"{identityServerUrl}/connect/authorize"),
TokenUrl = new Uri($"{identityServerUrl}/connect/token"),
Scopes = new Dictionary<string, string>
{
{ "openapi", "接口访问权限" },
}
}
}
});
});
在中间件管道中使用
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint(string.Format("/swagger/{0}/swagger.json", configuration["Perfect:Swagger:Name"]), configuration["Perfect:Swagger:Title"]);
c.OAuthClientId(configuration["Perfect:Swagger:ClientId"]);
c.OAuthClientSecret(configuration["Perfect:Swagger:ClientSecret"]);
c.OAuthAppName(configuration["Perfect:Swagger:AppName"]);
c.OAuthUsePkce();
});
编译运行,打开swagger页面
源码地址:https://github.com/dreamdocker/zerostack
以上教学来自零度课堂,本人只是分享,无其他意义,开会员记得找我哦!
在项目中自定义集成IdentityService4的更多相关文章
- Atitit.mybatis的测试 以及spring与mybatis在本项目中的集成配置说明
Atitit.mybatis的测试 以及spring与mybatis在本项目中的集成配置说明 1.1. Mybatis invoke1 1.2. Spring的数据源配置2 1.3. Mybatis ...
- Captcha服务(后续2)— 改造Captcha服务之Asp.Net Core项目中如何集成TypeScript
环境准备 .Net Core 版本:下载安装.Net Core SDK,安装完成之后查看sdk版本 ,查看命令dotnet --version,我的版本是2.2.101 IDE: Visual Stu ...
- 五分钟后,你将学会在SpringBoot项目中如何集成CAT调用链
买买买结算系统 一年一度的双十一购物狂欢节就要到了,又到剁手党们开始表演的时刻了.当我们把种草很久的商品放入购物车以后,点击"结算"按钮时,就来到了买买买必不可少的结算页面了.让我 ...
- php 项目中自定义日志方法
在现在项目中之前没有定义日志的方法,每次调试起来很麻烦,经常不能输出参数,只能用写日志的方法,一直用file_put_contents很烦躁,于是用了一点时间,写了这样一个方法: <?php / ...
- 如何在spingboot项目中自定义自己的配置
在实际开发中,为了方便我们常常会考虑把配置文件的某一类配置映射到配置类上,方便spring容器加载,实现方法如下: 1. 书写配置文件信息:书写某一类特定字段开头的配置信息,例如在yml配置文件中可以 ...
- 在django项目中自定义manage命令(转)
add by zhj 是我增加的注释 原文:http://www.cnblogs.com/holbrook/archive/2012/03/09/2387679.html 我们都用过Django的dj ...
- 前后端分离项目中后台集成shiro需要注意的二三事
1. 修改 Shiro 认证失败后默认重定向处理问题 a. 继承需要使用的 ShiroFilter,重载 onAccessDenied() 方法: @Override protected boolea ...
- vue 项目中 自定义 webpack 的 配置文件(webpack.config.babel.js)
webpack.config.babel.js,这样命名是想让webpack在编译的时候自动识别es6的语法,现在貌似不需要这样命名了,之前用webpack1.x的时候貌似是需要的 let path ...
- SpringBoot项目中自定义注解的使用
1.定义注解接口 @Documented @Retention(RUNTIME) @Target(METHOD) public @interface MyLog { String value() ...
随机推荐
- javaweb 02: servlet
Servlet对象的生命周期 什么是Servlet对象生命周期? Servlet对象什么时候被创建. Servlet对象什么时候被销毁. Servlet对象创建了几个? Servlet对象的生命周期表 ...
- HTML js 复习
<a href="#top" target="_self">返回顶部</a> 返回页面顶部代码 打印js对象方法 function wr ...
- (转)git使用收集
由于最近项目开始弃SVN用git,特意整理下git命令.原文链接为http://www.jb51.net/article/55442.htm git branch 查看本地所有分支git status ...
- Dapr学习(4)之eShopOnDapr部署(Rancher2.63&k3s)
本篇主要讲述一下github上基于Dapr实现的商城demo在(K8s or K3s)环境中的部署实践,本文环境基于k3s&rancher2.6.3 1.eShopOnDapr源代码及概述 源 ...
- 8月Meetup | “数据调度+分析引擎”解锁企业数字化转型之路
编辑切换为居中 添加图片注释,不超过 140 字(可选) 大数据是一种规模大到在获取.存储.管理.分析方面大大超出了传统数据库软件工具能力范围的数据集合,而大数据作为企业运转的基础,只有经过提 ...
- Apache DolphinScheduler 社区呼唤志愿者
DolphinScheduler是什么? Apache DolphinScheduler 是一个分布式.易扩展并带有强大的可视化界面的大数据工作流调度系统. 2021 年 03 月 18 日正式成为 ...
- 巨细靡遗流程控制,Go lang1.18入门精炼教程,由白丁入鸿儒,Go lang流程结构详解EP09
流程结构就是指程序逻辑到底怎么执行,进而言之,程序执行逻辑的顺序.众所周知,程序整体都是自上由下执行的,但有的时候,又不仅仅是从上往下执行那么简单,大体上,Go lang程序的流程控制结构一共有三种: ...
- LuoguP2575 高手过招(博弈论)
空格数变吗?不变呀 阶梯博弈阶梯数变吗?不变呀 那这不就阶梯博弈,每行一栋楼,爬完\(mex\)就可以了吗? #include <iostream> #include <cstdio ...
- 用VS Code搞Qt6:至简窗口部件——QWidget
在正题开始之前,老周照例扯点别的.嗯,咱们扯一下在 VS 2022 下结合 CMake 开发 Qt6 时的环境变量设置问题.在VS Code 中,通够通过 CMake Tools 扩展的配置来设置环境 ...
- 在 IconFont 上获取图标资源的操作方法与感悟
如何在 IconFont 上获取图标资源 阿里巴巴矢量图标库网站(https://www.iconfont.cn/)上提供了非常丰富的图标资源,包括 SVG.AI.PNG.字体图标等格式.使用该网站提 ...