IdentityServer4【QuickStart】之利用OpenID Connect添加用户认证
利用OpenID Connect添加用户认证
利用OpenID Connect添加用户认证
在这个示例中我们想要通过OpenID Connect协议将交互用户添加到我们的IdentityServer上面。
准备就绪后,我们会创建一个MVC的应用来使用IdentityServer做认证。
添加UI
关于该协议支持所需要的一切都内建到了IdentityServer中,你需要为登陆、登出、确认和错误等提供必要的UI页面。
虽然在每一个实现了IdentityServer的服务中它所实现的外观和工作流程等都是不一样的,我们提供了一个MVC模板,你可以将其作为起点。
可以从 Quickstart UI repo找到这个示例。你可以(使用github)克隆或者下载到你的桌面然后将控制器、视图、模型和Css样式表等放到你的应用里面。
你也可以在你的项目的根目录下面运行下面这个命令行(在powershell)进行自动的安装:
iex ((New-Object System.Net.WebClient).DownloadString('https://raw.githubusercontent.com/IdentityServer/IdentityServer4.Quickstart.UI/release/get.ps1'))
一点你安装好了这些之后,你也需要在Startup类中配置好你的MVC,这需要在ConfigureService里面将MVC添加到DI中并在Configure方法中将MVC中间件添加到管道上。
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc(); // configure identity server with in-memory stores, keys, clients and scopes
services.AddIdentityServer()
.AddDeveloperSigningCredential()
.AddInMemoryApiResources(Config.GetApiResources())
.AddInMemoryClients(Config.GetClients())
.AddTestUsers(Config.GetUsers());
}
并且应该将MVC作为管道的最后一个中间件:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
} app.UseIdentityServer(); app.UseStaticFiles();
app.UseMvcWithDefaultRoute();
}
从readme可以看到更多的信息。
花费一些时间检查以下控制器和模型,你越了解他们,在后续的升级和改造过程中也会越容易。大多数代码都保存在一个QuickStart的文件夹中。如果这种方式不适合你的话,你可以自己修改成你要的风格。
创建一个MVC客户端
下一步你得创建一个MVC的应用。使用Asp.net core自带的模板就可以。不要配置认证信息。关于认证的信息需要你在应用里面自己配置。一旦你创建好应用后,将应用的端口号配置到5002上面。
为了添加对OpenID Connect认证的支持,需要在Startup类中的ConfigureService方法中进行如下的配置。
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc(); JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear(); services.AddAuthentication(options =>
{
options.DefaultScheme = "Cookies";
options.DefaultChallengeScheme = "oidc";
})
.AddCookie("Cookies")
.AddOpenIdConnect("oidc", options =>
{
options.SignInScheme = "Cookies"; options.Authority = "http://localhost:5000";
options.RequireHttpsMetadata = false; options.ClientId = "mvc";
options.SaveTokens = true;
});
}
AddAuthentication 方法将认证服务添加到了DI系统中,我们使用了一个cookie作为认证用户的主要手段(通过options.DefaultScheme=“Cookies”来指定)。我们将DefaultChallengeScheme设置成“oidc”使用为当我们需要用户登陆的时候,我们要使用OpenID Connect的scheme。
然后我们使用AddCookie方法添加一个对应的处理Cookie的handler(对应于options.DefaultScheme=“”Cookies“这个配置)。
最后,AddOpenIdConnect方法配置了相应的handler(对应于options.DefaultChallengeScheme=”oidc”)来执行OpenID Connect协议。Authority指定了我们要新人的IdentityServer;然后通过ClientId标志了客户端;SiginScheme=“Cookies“这个表示当OpenId Connect协议执行完成之后会使用cookie handler来发布cookie。
此外,我们关闭了JWT claim的类型映射以允许OpenId Connect中的claim类型。
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
然后为了认证服务会在每个请求中都执行,需要在Startup类中的Configure方法中配置认证的中间件:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
} app.UseAuthentication(); app.UseStaticFiles();
app.UseMvcWithDefaultRoute();
}
认证中间件应该放在MVC的前面。
最后一步是要触发认证。我们需要在home控制器上面添加[Autorize]特性。同时修改一下about页面:
<dl>
@foreach (var claim in User.Claims)
{
<dt>@claim.Type</dt>
<dd>@claim.Value</dd>
}
</dl>
如果你现在使用浏览器访问了刚才配置好的控制器的路径,那么会有一个重定向发送到IdentityServer。这回导致一个错误因为MVC客户端还没有注册到Identityserver。
添加对OpenID Connect Identity Scopes的支持
和OAuth2.0相似的是,OpenID Connect同样使用了scopes这个概念。再一次声明:scopes代表了你想要保护的,同时,也是客户端想要访问的那种东西。与OAuth对比一下,scopes在OIDC中并不代表APIs,而是代表了用户的数据,比如user id、name或者email等。
在这里阐述一下:scopes在OIDC里面是和claim挂钩的,他们之间的关系是1对多。打个比方,profile里面包含了许多的claim,包括first_name last_name等等。。
在Config类中添加一个帮助方法,这个方法创建了一个IdentityResource的集合,它添加了对标准openid(subject id)和profile(用户的名、姓等等)scopes的支持。
public static IEnumerable<IdentityResource> GetIdentityResources()
{
return new List<IdentityResource>
{
new IdentityResources.OpenId(),
new IdentityResources.Profile(),
};
}
所有标准scopes对应的claims都能在specification找到。
然后你得将上面配置好的添加到ConfgureService方法中,使用AddInmemoryIdentityResource:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc(); // configure identity server with in-memory stores, keys, clients and scopes
services.AddIdentityServer()
.AddDeveloperSigningCredential()
.AddInMemoryIdentityResources(Config.GetIdentityResources())
.AddInMemoryApiResources(Config.GetApiResources())
.AddInMemoryClients(Config.GetClients())
.AddTestUsers(Config.GetUsers());
}
添加一个客户端用于演示OpenID Connect的隐式流程
最后一步是在IdentityServer中为MVC客户端添加一个新的入口。
在IdentitySErver中配置基于OpenId Connect的客户端和配置OAuth2.0的客户端有些相似。但是因为在OpenID Connect中经常会有交互发生,所有我们需要在配置中添加一写重定向。
在客户端配置的代码中写入如下:
public static IEnumerable<Client> GetClients()
{
return new List<Client>
{
// other clients omitted... // OpenID Connect implicit flow client (MVC)
new Client
{
ClientId = "mvc",
ClientName = "MVC Client",
AllowedGrantTypes = GrantTypes.Implicit, // where to redirect to after login
RedirectUris = { "http://localhost:5002/signin-oidc" }, // where to redirect to after logout
PostLogoutRedirectUris = { "http://localhost:5002/signout-callback-oidc" }, AllowedScopes = new List<string>
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile
}
}
};
}
测试客户端
现在终于都办妥了。
导航到被保护的控制器上以便触发认证,这时你会发现被重定向到了IdentitySErver上的登陆页面:

登陆成功后,会给用户呈现一个确认页面。在这里用户可以决定他是否要将一些访问资源的权限交给客户端。
确认页面可以在配置中的RequireConsent属性上取消。

最终页面会跳转到客户端应用上,展示用户的claim。

添加登出
在添加一个登出的功能吧。
使用像identity server这样的身份验证服务,只需要清除本地应用程序cookie就不够了。此外,你还需要对身份服务器进行一次往返,以清除中心单点登录会话。
确切的协议步骤是在OpenID Connect中间件中实现的,只需将以下代码添加到某个控制器中以触发信号:
public async Task Logout()
{
await HttpContext.SignOutAsync("Cookies");
await HttpContext.SignOutAsync("oidc");
}
这将会清除本地的cookie然后重定向到Identityserver。Identtiyserver会清除它的Cookie然后给用户一个返回MVC应用的链接。
进一步的尝试
就像上面提到的,OpenId Connect中间件默认会请求profile scope。这个scope中包含了诸如name website等claim。
将这些claim添加到TestUser上面,这样一来IdentityServer可以将他们放到Id token里面:
public static List<TestUser> GetUsers()
{
return new List<TestUser>
{
new TestUser
{
SubjectId = "",
Username = "alice",
Password = "password", Claims = new []
{
new Claim("name", "Alice"),
new Claim("website", "https://alice.com")
}
},
new TestUser
{
SubjectId = "",
Username = "bob",
Password = "password", Claims = new []
{
new Claim("name", "Bob"),
new Claim("website", "https://bob.com")
}
}
};
}
下一次你再认证的时候,你的展示claims的页面就会展示这些额外的claim了。
试着任意添加一些claim,或者更多的scopes。在OpenId Connect中间件中的Scope属性上面进行的配置会决定你发送到IdentityServer的认证请求中会包含那些scopes:
services.AddAuthentication(option =>
{
option.DefaultScheme = "cookies";
option.DefaultChallengeScheme = "oidc";
}).AddCookie("cookies").AddOpenIdConnect("oidc", option =>
{
option.Scope.Add("somescope");//这句
});
同样值得注意的是,检索令牌的claim是一个可扩展点----IProfileService。因为我们使用AddTestUsers,TestUserProfileService是默认被使用的。你可以检查源代码here 来看看它是如何工作的。
IdentityServer4【QuickStart】之利用OpenID Connect添加用户认证的更多相关文章
- .NET Core IdentityServer4实战 第二章-OpenID Connect添加用户认证
内容:本文带大家使用IdentityServer4进行使用OpenID Connect添加用户认证 作者:zara(张子浩) 欢迎分享,但需在文章鲜明处留下原文地址. 在这一篇文章中我们希望使用Ope ...
- asp.net core系列 56 IS4使用OpenID Connect添加用户认证
一.概述 在前二篇中讲到了客户端授权的二种方式: GrantTypes.ClientCredentials凭据授权和GrantTypes.ResourceOwnerPassword密码授权,都是OAu ...
- ASP.NET Core的身份认证框架IdentityServer4(9)-使用OpenID Connect添加用户认证
OpenID Connect OpenID Connect 1.0是OAuth 2.0协议之上的一个简单的身份层. 它允许客户端基于授权服务器执行的身份验证来验证最终用户的身份,以及以可互操作和类似R ...
- IdentityServer4 中文文档 -11- (快速入门)添加基于 OpenID Connect 的用户认证
IdentityServer4 中文文档 -11- (快速入门)添加基于 OpenID Connect 的用户认证 原文:http://docs.identityserver.io/en/releas ...
- IdentityServer4 使用OpenID Connect添加用户身份验证
使用IdentityServer4 实现OpenID Connect服务端,添加用户身份验证.客户端调用,实现授权. IdentityServer4 目前已更新至1.0 版,在之前的文章中有所介绍.I ...
- 【转载】IdentityServer4 使用OpenID Connect添加用户身份验证
使用IdentityServer4 实现OpenID Connect服务端,添加用户身份验证.客户端调用,实现授权. IdentityServer4 目前已更新至1.0 版,在之前的文章中有所介绍.I ...
- IdentityServer4(9)- 使用OpenID Connect添加用户身份验证(implicit)
本文为 OpenID Connect 简化模式(implicit) 已更新至.NET Core 2.2 在本快速入门中,我们希望通过 OpenID Connect 协议向我们的 IdentitySer ...
- Identity Server 4使用OpenID Connect添加用户身份验证(三)
一.说明 基于上一篇文章中的代码进行继续延伸,只需要小小的改动即可,不明白的地方可以先看看本人上一篇文章及源码: Identity Server 4资源拥有者密码认证控制访问API(二) GitHub ...
- 第11章 使用OpenID Connect添加用户身份验证 - Identity Server 4 中文文档(v1.0.0)
在本快速入门中,我们希望通过OpenID Connect协议向我们的IdentityServer添加对交互式用户身份验证的支持. 一旦到位,我们将创建一个将使用IdentityServer进行身份验证 ...
随机推荐
- Eric Chen Mock Interview
Given an array with integers. Find two non-overlapping subarrays A and B, which |SUM(A) - SUM(B)| is ...
- CSS染色图标(图片)
之前一直以为用background引入的图标无法染色(非字体图标),现在才知道有黑科技可以用,就是利用drop-shadow. 代码示例 <!DOCTYPE html> <html& ...
- Java序列化(含transient)
什么是序列化? 我们创建的对象只有在Java虚拟机保持运行时,才会存在于内存中.如果想要超出Java虚拟机的生命周期,就可以将对象序列化,将对象状态转换为字节序列,写入文件(或socket传输),后面 ...
- Nginx的configure各项中文说明
–prefix=<path> – Nginx安装路径.如果没有指定,默认为 /usr/local/nginx. –sbin-path=<path> – Nginx可执行文件安装 ...
- 快速排序 O(n logn) 堆排序 O(n logn) 归并排序 O(n logn)
NB三人组 快速排序 思路" 取一个元素P (第一个元素), 使元素归位 列表被P 分成两部分,左边都比P小,右边比P大; 递归完成排序. 问题 如果是已经排序好的 倒叙 列表 则会 递归深 ...
- 设计模式のFlyweight(享元模式)----结构模式
一.产生背景 享元模式:它使用共享物件,用来尽可能减少内存使用量以及分享资讯给尽可能多的相似物件:它适合用于只是因重复而导致使用无法令人接受的大量内存的大量物件.通常物件中的部分状态是可以分享.常见做 ...
- 关于HashMap的一些深入探索与理解
在java中.大家差点儿是离不开对集合的使用的,像Map系列,List系列.Set系列.可是非常多人没有了解过或者研究过这些集合类究竟能够用在什么地方,而且有什么注意的地方.因此本文分Map系列和Li ...
- display为inline-block的元素有内容和没有内容情况下高度不一致的问题
这两天发现一个问题,就是display为inline-block的元素有内容和没有内容情况下高度不一致,虽然不会出现元素中没内容的情况,但是我还是决定必须解决这个问题,可能我有一些轻微的强迫症. &l ...
- 【vue】vue-router的用法
依赖安装:(c)npm install vue-router 过程: import Vue from 'vue'; import Router from 'vue-router'; Vue.use(R ...
- C#使用Json.Net遍历Json
StringBuilder builder=new StringBuilder(); builder.AppendLine("{"); builder.AppendLine(&qu ...