接着上一篇讲:https://www.cnblogs.com/nsky/p/10352678.html

我们之前都是用in-men的方式把数据添加到内存了,目的是为了测试方便,

现在我们把所有配置都添加到数据库中

用IdeneityServer4 + EntityFramework + ASP.NET Identity的方式

上篇已经讲过identity和profile的对接,这里讲讲配置信息

之前都是这样做的

添加包:IdentityServer4.EntityFramework

里面有专门的2个DbContext管理对应的信息

分别是:PersistedGrantDbContext 和 ConfigurationDbContext

如果还记得Identity,里面有个ApplicationDbContext

所以这里总共有3个DbContext

ApplicationDbContext
PersistedGrantDbContext
ConfigurationDbContext

ApplicationDbContext - 负责涉及ASP.NET Identity的用户所以表
dbo.AspNetRoleClaims
dbo.AspNetRoles
dbo.AspNetUserClaims
dbo.AspNetUserLogins
dbo.AspNetUserRoles
dbo.AspNetUsers
dbo.AspNetUserTokens

PersistedGrantDbContext - 负责存储同意,授权代码,刷新令牌和引用令牌
dbo.PersistedGrants

ConfigurationDbContext - 负责数据库中剩余的所有其他内容

所以关于迁移,如果我更新任何AspNet Identity模型(即ApplicationUser),那么我将在ApplicationDbContext上运行迁移。

任何客户端表或其他范围都将在ConfigurationDbContext上运行。并且访问entites(或表)将是相应的上下文。

添加包之后,添加依赖注入配置

 .AddConfigurationStore(options =>
{
options.ConfigureDbContext = builder =>
{
builder.UseSqlServer(Configuration.GetConnectionString("conn"),
sql => sql.MigrationsAssembly(migrationAssembly));
};
}) /*
这里存储的是,给用户授权的token和一些授权信息
添加来自数据库的操作数据(codes, tokens, consents)
*/
.AddOperationalStore(options =>
{
options.ConfigureDbContext = builder =>
{
builder.UseSqlServer(Configuration.GetConnectionString("conn"),
sql => sql.MigrationsAssembly(migrationAssembly));
};
})
migrationAssembly是当前程序集;
 var migrationAssembly = typeof(Startup).GetTypeInfo().Assembly.GetName().Name; 接下来生成migration,在项目的程序包管理控制台输入:
 Add-Migration InitConfiguration  -Context ConfigurationDbContext -o Date\Migrations\IdentityServer\ConfiguragtionDb
 Add-Migration InitConfiguration -Context PersistedGrantDbContext -o Date\Migrations\IdentityServer\PersistedGrantDb
这样就添加了两个migration
执行update-database生成表
update-database -context ConfigurationDbContext Update-Database -Context PersistedGrantDbContext
这样就生成了表

因为现在还没有界面录入,可以先手动初始化配置文件 到数据库,因为之前有config.cs
可以直接映射到model写入数据库
  /// <summary>
/// 因为现在没有通过UI去录入api,client等信息
/// 所有可以先init一些默认信息写入数据库
/// </summary>
/// <param name="app"></param>
public void InitIdentityServerDataBase(IApplicationBuilder app)
{
//ApplicationServices返回的就是IServiceProvider,依赖注入的容器
using (var scope = app.ApplicationServices.CreateScope())
{
//Update-Database
scope.ServiceProvider.GetService<PersistedGrantDbContext>().Database.Migrate(); //var provide = scope.ServiceProvider.GetService<PersistedGrantDbContext>();
//ckk.PersistedGrants.Add(new IdentityServer4.EntityFramework.Entities.PersistedGrant { //}); var configurationDbContext = scope.ServiceProvider.GetRequiredService<ConfigurationDbContext>(); /*
如果不走这个,
那么应该手动执行 Update-Database -Context PersistedGrantDbContext
*/
configurationDbContext.Database.Migrate(); if (!configurationDbContext.Clients.Any())
{
foreach (var client in Config.GetClients())
{
//client.ToEntity() 会把当前实体映射到EF实体
configurationDbContext.Clients.Add(client.ToEntity());
}
configurationDbContext.SaveChanges();
}
if (!configurationDbContext.ApiResources.Any())
{
foreach (var api in Config.GetApiResources())
{
configurationDbContext.ApiResources.Add(api.ToEntity());
}
configurationDbContext.SaveChanges();
}
if (!configurationDbContext.IdentityResources.Any())
{
foreach (var identity in Config.GetIdentityResource())
{
configurationDbContext.IdentityResources.Add(identity.ToEntity());
}
configurationDbContext.SaveChanges();
}
}
}

在Configure中调用

InitIdentityServerDataBase(app);

dotnet run就有数据了

客户端不用配置,

获取refresh_token,混合模式是支持refresh_token的

详情:https://www.cnblogs.com/jesse2013/p/oidc-in-aspnetcore-with-identity-server.html

IdentityResource新增offline_access身份

AllowedScopes可以不用加: IdentityServerConstants.StandardScopes.OfflineAccess

服务端Client设置允许: AllowOfflineAccess = true,
客户端配置:options.Scope.Add("offline_access");

拿到这个refresh_token,可以刷新access_token

一个refresh_token只能用一次,否则:
通过这个access_token就看访问资源api了
但就算授权了。也只能访问授权的api
identityResurce是资源信息,AllowedScopes设置了
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Email,
IdentityServerConstants.StandardScopes.Profile, 就会返回这些信息,
OpenId是必须要的,因为OIDC要通过openid确认身份

Profile是可选的,只是客户端默认是传了Profile的,
因为oidc就是为了返回用信息而来的 Profile包含了一些基本的信息
name
family_name
given_name
middle_name
nickname
preferred_username
profile
picture
website
gender
birthdate
zoneinfo
locale
updated_at
Email包含了email 和 email_verified
这些从源码可以看到:
https://github.com/IdentityServer/IdentityServer4/blob/63a50d7838af25896fbf836ea4e4f37b5e179cd8/src/Constants.cs
所以客户端获取的cliams是这些

因为profile是在我们的ProfileServices类返回的

那么如果用户没有选择

是不是应该不返回profile信息呢?

GetProfileDataAsync方法的context可以拿到当前请求的IdentityResources和ApiResource

好像通过 var claimTypes = context.RequestedClaimTypes;也可以判断,选择了profile,那么RequestedClaimTypes是有值的

当然除了了一些基本信息外,客户端还想获取其他资源,这也是可以的

比如资源服务器有个接口,获取额外的信息,scope叫:OtherInfo



客户端请求scope:options.Scope.Add("OtherInfo");

可以看到上面是身份信息,就是会返回的的用户信息

下面是权限,就是可以去资源服务器获取的那些权限,因为:access toke管的是权限

1:先不选择,拿到的access_token里面的scope是没有OtherInfo的

这里为啥有两个offline_access?我也不知道

2:如果选择的话。如果不出错的话是有的

 

那么资源服务器就可以根据当前这个scope来判断了

 [HttpGet]
public ActionResult GetOtherInfo()
{
//判断是否授权
var scope = User.Claims.FirstOrDefault(f => f.Type == "scope" && f.Value == "OtherInfo");
if (scope != null)
{
return new JsonResult(
new
{
phone = "",
address = "china",
age = "",
gender = "m",
hobby = "coding"
}
);
}
else //禁止访问
{
return BadRequest(StatusCodes.Status403Forbidden);
}
}

如果授权请求了OtherInfo请求是成功了

当没有授权OtherInfo的时候,当然,返回什么信息你可以自己定义

这说明你只有权限访问资源服务器,授权了的api。

如果你的access_token是错误的。就说明你没有授权,你都没有机会进入api,会提示401

或者写一个过滤器,弄个接口规范,获取某些参数进行判断

目前我想到的方法就是这样,也许不是最好的

既然access_token包含profile信息,它又是JWT类型,那是不是可以DeCode呢?

答案是可以的:

界面输出

源码:https://github.com/byniqing/OAuth2Authorization

参考:https://cloud.tencent.com/developer/article/1048128

												

IdentityServer4授权和认证对接数据库的更多相关文章

  1. IdentityServer4授权和认证集成Identity和profile

    identiyt的使用可以看之前的文章:https://www.cnblogs.com/nsky/p/10323415.html 之前的ids4授权服务器都是用的in-men方式把数据添加到内存, 现 ...

  2. IdentityServer4授权和认证

    IdentityServer4 简称ids4 oidc了解:http://www.jessetalk.cn/2018/04/04/oidc-asp-net-core/ 是一个去中心化的网上身份认证系统 ...

  3. Angular SPA基于Ocelot API网关与IdentityServer4的身份认证与授权(四)

    在上一讲中,我们已经完成了一个完整的案例,在这个案例中,我们可以通过Angular单页面应用(SPA)进行登录,然后通过后端的Ocelot API网关整合IdentityServer4完成身份认证.在 ...

  4. Angular SPA基于Ocelot API网关与IdentityServer4的身份认证与授权(一)

    好吧,这个题目我也想了很久,不知道如何用最简单的几个字来概括这篇文章,原本打算取名<Angular单页面应用基于Ocelot API网关与IdentityServer4+ASP.NET Iden ...

  5. Angular SPA基于Ocelot API网关与IdentityServer4的身份认证与授权(二)

    上文已经介绍了Identity Service的实现过程.今天我们继续,实现一个简单的Weather API和一个基于Ocelot的API网关. 回顾 <Angular SPA基于Ocelot ...

  6. Angular SPA基于Ocelot API网关与IdentityServer4的身份认证与授权(三)

    在前面两篇文章中,我介绍了基于IdentityServer4的一个Identity Service的实现,并且实现了一个Weather API和基于Ocelot的API网关,然后实现了通过Ocelot ...

  7. Asp.Net Core 中IdentityServer4 授权中心之应用实战

    一.前言 查阅了大多数相关资料,查阅到的IdentityServer4 的相关文章大多是比较简单并且多是翻译官网的文档编写的,我这里在 Asp.Net Core 中IdentityServer4 的应 ...

  8. Asp.Net Core 中IdentityServer4 授权中心之自定义授权模式

    一.前言 上一篇我分享了一篇关于 Asp.Net Core 中IdentityServer4 授权中心之应用实战 的文章,其中有不少博友给我提了问题,其中有一个博友问我的一个场景,我给他解答的还不够完 ...

  9. Asp.Net Core 中IdentityServer4 授权原理及刷新Token的应用

    一.前言 上面分享了IdentityServer4 两篇系列文章,核心主题主要是密码授权模式及自定义授权模式,但是仅仅是分享了这两种模式的使用,这篇文章进一步来分享IdentityServer4的授权 ...

随机推荐

  1. SSH下authorized_keys, id_rsa, id_rsa.pub, known_hosts作用

    一.known_hsots ssh会把你每个你访问过计算机的公钥(public key)都记录在~/.ssh/known_hosts.当下次访问相同计算机时,OpenSSH会核对公钥.如果公钥不同,O ...

  2. 想拥有一款钢铁侠Jarvis管家的软件吗?

    漫威的<钢铁侠>电影很好看,里面钢铁侠的管家Jarvis,可以说非常酷.既能管理日常生活,还能组装钢铁战衣.跟随托尼出生入死,形影不离. 那么现实生活中,想不想拥有这一款软件?看看下面这个 ...

  3. WebStorm Chinese Language Pack(中文语言包

    https://github.com/ewen0930/WebStorm-Chinese http://ewen0930.github.io/2016/04/webstorm-chinese-lang ...

  4. 关于JVM内存的N个问题

    JVM的内存区域是怎么划分的? JVM的内存划分中,有部分区域是线程私有的,有部分是属于整个JVM进程:有些区域会抛出OOM异常,有些则不会,了解JVM的内存区域划分以及特征,是定位线上内存问题的基础 ...

  5. iOS之HTTP和HTTPS的基本知识和应用

    HTTPS的基本使用 1.https简单说明HTTPS(全称:Hyper Text Transfer Protocol over Secure Socket Layer),是以安全为目标的HTTP通道 ...

  6. windows下设置PHP环境变量

    1.找到“高级系统设置”(二选一的方法找到环境变量) ① 我的电脑-属性-高级-环境变量 ②win8,10 直接在搜索框搜 “查看高级系统设置”-环境变量 2.找到变量"Path" ...

  7. 第四天,通过windows来执行第一个python文件步骤

    该看 第 38部分的啦

  8. <?php if($value['udertype'] == 0) {?> <td>超级管理员</td> <?php } else if ($value['udertype'] == 1)

    <?php if($value['udertype'] == 0) {?> <td>超级管理员</td> <?php } else if ($value['u ...

  9. 18.jwt加密

    jwt 官网https://jwt.io/ jwt:json web token jwt-simple: https://www.npmjs.com/package/jwt-simple jsonwe ...

  10. sshfs远程挂载

    一.什么是 SSHFSSSHFS(Secure SHell FileSystem)是一个客户端,可以让我们通过 SSH 文件传输协议(SFTP)挂载远程的文件系统并且在本地机器上和远程的目录和文件进行 ...