一、说明

基于上一篇文章中的代码进行继续延伸,只需要小小的改动即可,不明白的地方可以先看看本人上一篇文章及源码 Identity Server 4资源拥有者密码认证控制访问API(二)

GitHub项目源码:https://github.com/li215704087/IdentityServer4

二、添加UI

官方GitHub:https://github.com/IdentityServer/IdentityServer4.Quickstart.UI

OpenID Connect 所需的所有协议支持都已内置到 IdentityServer 中。您需要为提供必要的UI部件:登录,注销,同意授权和错误页面。

根据业务场景的不同对 IdentityServer 的实现也有所不同,但我们提供了一个基于 MVC 的示例UI,您可以将其用作起步。

可以在快速入门UI仓库中找到此UI。 您可以克隆或下载此repo,并将Controller,View,Model和CSS放入IdentityServer Web 应用程序中。

或者,您可以使用.NET CLI(从 QuickStartIdentityServer4 文件夹中运行命令):

dotnet new -i identityserver4.templates
dotnet new is4ui

添加 MVC UI 后,您还需要在 DI 系统和管道中启用 MVC。 当您查看Startup.cs时,您将在 ConfigureServices 和 Configure 方法中找到有关如何启用MVC的注释

三、运行QuickStartIdentityServer4项目

四、环境配置

一、QuickStartIdentityServer4项目中Config文件增加配置

 

// Clients集合中增加 基于OIDC客户端配置
new Client
{
ClientId="sample_mvc_client",
ClientName="Sample MVC Client",
ClientSecrets=
{
new Secret("sample_client_secret".Sha256())
},
AllowedGrantTypes=GrantTypes.Code,
RedirectUris={ "http://localhost:4001/signin-oidc"}, // 登录成功之后的回调地址
PostLogoutRedirectUris={ "http://localhost:4001/signout-callback-oidc" }, // 注销/登出之后的回调地址
AllowedScopes={
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
"sample_api" // 用于oidc认证成功之后访问项目API的范围api接口
},
RequireConsent=true // 是否需要用户同步,当用户登录的时候需要用户进行是否同意
}
// 基于OIDC协议
public static IEnumerable<IdentityResource> IdentityResources => new List<IdentityResource>
{
new IdentityResources.OpenId(),
new IdentityResources.Profile()
}; // 基于OIDC添加测试用户
public static List<TestUser> Users => new List<TestUser>() { new TestUser()
{
SubjectId="1",
Username="admin",
Password="123456777"
}
};

二、新增web项目Sample.MvcClient ,端口号4001   NuGet:Microsoft.AspNetCore.Authentication.OpenIdConnect

1、增加SameSiteCookiesServiceCollectionExtensions.cs扩展类,该类主要是为了解决认证成功,页面跳转异常问题

public static class SameSiteCookiesServiceCollectionExtensions
{
/// <summary>
/// -1 defines the unspecified value, which tells ASPNET Core to NOT
/// send the SameSite attribute. With ASPNET Core 3.1 the
/// <seealso cref="SameSiteMode" /> enum will have a definition for
/// Unspecified.
/// </summary>
private const SameSiteMode Unspecified = (SameSiteMode)(-1); /// <summary>
/// Configures a cookie policy to properly set the SameSite attribute
/// for Browsers that handle unknown values as Strict. Ensure that you
/// add the <seealso cref="Microsoft.AspNetCore.CookiePolicy.CookiePolicyMiddleware" />
/// into the pipeline before sending any cookies!
/// </summary>
/// <remarks>
/// Minimum ASPNET Core Version required for this code:
/// - 2.1.14
/// - 2.2.8
/// - 3.0.1
/// - 3.1.0-preview1
/// Starting with version 80 of Chrome (to be released in February 2020)
/// cookies with NO SameSite attribute are treated as SameSite=Lax.
/// In order to always get the cookies send they need to be set to
/// SameSite=None. But since the current standard only defines Lax and
/// Strict as valid values there are some browsers that treat invalid
/// values as SameSite=Strict. We therefore need to check the browser
/// and either send SameSite=None or prevent the sending of SameSite=None.
/// Relevant links:
/// - https://tools.ietf.org/html/draft-west-first-party-cookies-07#section-4.1
/// - https://tools.ietf.org/html/draft-west-cookie-incrementalism-00
/// - https://www.chromium.org/updates/same-site
/// - https://devblogs.microsoft.com/aspnet/upcoming-samesite-cookie-changes-in-asp-net-and-asp-net-core/
/// - https://bugs.webkit.org/show_bug.cgi?id=198181
/// </remarks>
/// <param name="services">The service collection to register <see cref="CookiePolicyOptions" /> into.</param>
/// <returns>The modified <see cref="IServiceCollection" />.</returns>
public static IServiceCollection ConfigureNonBreakingSameSiteCookies(this IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
options.MinimumSameSitePolicy = Unspecified;
options.OnAppendCookie = cookieContext =>
CheckSameSite(cookieContext.Context, cookieContext.CookieOptions);
options.OnDeleteCookie = cookieContext =>
CheckSameSite(cookieContext.Context, cookieContext.CookieOptions);
}); return services;
} private static void CheckSameSite(HttpContext httpContext, CookieOptions options)
{
if (options.SameSite == SameSiteMode.None)
{
var userAgent = httpContext.Request.Headers["User-Agent"].ToString(); if (DisallowsSameSiteNone(userAgent))
{
options.SameSite = Unspecified;
}
else
{
options.SameSite = SameSiteMode.Lax; // 增加这句
}
}
} /// <summary>
/// Checks if the UserAgent is known to interpret an unknown value as Strict.
/// For those the <see cref="CookieOptions.SameSite" /> property should be
/// set to <see cref="Unspecified" />.
/// </summary>
/// <remarks>
/// This code is taken from Microsoft:
/// https://devblogs.microsoft.com/aspnet/upcoming-samesite-cookie-changes-in-asp-net-and-asp-net-core/
/// </remarks>
/// <param name="userAgent">The user agent string to check.</param>
/// <returns>Whether the specified user agent (browser) accepts SameSite=None or not.</returns>
private static bool DisallowsSameSiteNone(string userAgent)
{
// Cover all iOS based browsers here. This includes:
// - Safari on iOS 12 for iPhone, iPod Touch, iPad
// - WkWebview on iOS 12 for iPhone, iPod Touch, iPad
// - Chrome on iOS 12 for iPhone, iPod Touch, iPad
// All of which are broken by SameSite=None, because they use the
// iOS networking stack.
// Notes from Thinktecture:
// Regarding https://caniuse.com/#search=samesite iOS versions lower
// than 12 are not supporting SameSite at all. Starting with version 13
// unknown values are NOT treated as strict anymore. Therefore we only
// need to check version 12.
if (userAgent.Contains("CPU iPhone OS 12")
|| userAgent.Contains("iPad; CPU OS 12"))
{
return true;
} // Cover Mac OS X based browsers that use the Mac OS networking stack.
// This includes:
// - Safari on Mac OS X.
// This does not include:
// - Chrome on Mac OS X
// because they do not use the Mac OS networking stack.
// Notes from Thinktecture:
// Regarding https://caniuse.com/#search=samesite MacOS X versions lower
// than 10.14 are not supporting SameSite at all. Starting with version
// 10.15 unknown values are NOT treated as strict anymore. Therefore we
// only need to check version 10.14.
if (userAgent.Contains("Safari")
&& userAgent.Contains("Macintosh; Intel Mac OS X 10_14")
&& userAgent.Contains("Version/"))
{
return true;
} // Cover Chrome 50-69, because some versions are broken by SameSite=None
// and none in this range require it.
// Note: this covers some pre-Chromium Edge versions,
// but pre-Chromium Edge does not require SameSite=None.
// Notes from Thinktecture:
// We can not validate this assumption, but we trust Microsofts
// evaluation. And overall not sending a SameSite value equals to the same
// behavior as SameSite=None for these old versions anyways.
if (userAgent.Contains("Chrome/5") || userAgent.Contains("Chrome/6"))
{
return true;
} return false;
}
}

2、Startup配置

public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
JwtSecurityTokenHandler.DefaultMapInboundClaims=false;
services.AddAuthentication(options => {
options.DefaultScheme = "Cookies";
options.DefaultChallengeScheme = "oidc";
//options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
})
.AddCookie("Cookies")
.AddOpenIdConnect("oidc", options => {
options.Authority = "http://localhost:5001";
options.ClientId = "sample_mvc_client";
options.ClientSecret = "sample_client_secret";
options.ResponseType = "code"; // 隐式授权时不用此段代码
options.SaveTokens=true;
options.Scope.Add("sample_api"); // 授权成功之后,如项目中无需访问基于范围认证api可不用此段代码
options.RequireHttpsMetadata = false; // 不采用https回调
}); services.ConfigureNonBreakingSameSiteCookies(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
app.UseStaticFiles(); app.UseRouting(); // 使用cookie
app.UseCookiePolicy();
// 添加认证中间件
app.UseAuthentication();
app.UseAuthorization(); app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
}

3、控制器增加如下方法

/// <summary>
/// 登出
/// </summary>
/// <returns></returns>
public IActionResult LogOut()
{
return SignOut("Cookies","oidc");
} /// <summary>
/// 模拟请求api
/// </summary>
/// <returns></returns>
public async Task<IActionResult> CallApi()
{
// 获取访问令牌
var accessToken = await HttpContext.GetTokenAsync("access_token");
// 创建HTTP客户端
var client = new HttpClient();
// 设置授权请求头
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
// 请求API
var content = await client.GetStringAsync("http://localhost:5000/IdentityServer");
// 转换api返回结果
ViewBag.Josn = JArray.Parse(content).ToString();
return View();
} [Authorize]
public IActionResult Privacy()
{
return View();
}

4、Privacy.cshtml页面配置

<div><a href='@Url.Action("LogOut")'>登出</a>&nbsp;&nbsp;&nbsp; <a href='@Url.Action("CallApi")'>模拟请求api</a></div>
<br />
<br />
<dl>
用户信息
@foreach (var claim in User.Claims)
{
<dt>@claim.Type</dt>
<dt>@claim.Value</dt>
}
</dl> <dl>
认证信息
@foreach (var prop in (await Context.AuthenticateAsync()).Properties.Items)
{
<dt>@prop.Key</dt>
<dt>@prop.Value</dt>
} </dl>

五、项目运行效果

1、同时启动API、QuickStartIdentityServer4、Sample.MvcClient

2、登出

3、模拟请求api

Identity Server 4使用OpenID Connect添加用户身份验证(三)的更多相关文章

  1. IdentityServer4 使用OpenID Connect添加用户身份验证

    使用IdentityServer4 实现OpenID Connect服务端,添加用户身份验证.客户端调用,实现授权. IdentityServer4 目前已更新至1.0 版,在之前的文章中有所介绍.I ...

  2. 【转载】IdentityServer4 使用OpenID Connect添加用户身份验证

    使用IdentityServer4 实现OpenID Connect服务端,添加用户身份验证.客户端调用,实现授权. IdentityServer4 目前已更新至1.0 版,在之前的文章中有所介绍.I ...

  3. 第11章 使用OpenID Connect添加用户身份验证 - Identity Server 4 中文文档(v1.0.0)

    在本快速入门中,我们希望通过OpenID Connect协议向我们的IdentityServer添加对交互式用户身份验证的支持. 一旦到位,我们将创建一个将使用IdentityServer进行身份验证 ...

  4. IdentityServer4(9)- 使用OpenID Connect添加用户身份验证(implicit)

    本文为 OpenID Connect 简化模式(implicit) 已更新至.NET Core 2.2 在本快速入门中,我们希望通过 OpenID Connect 协议向我们的 IdentitySer ...

  5. .NET Core IdentityServer4实战 第二章-OpenID Connect添加用户认证

    内容:本文带大家使用IdentityServer4进行使用OpenID Connect添加用户认证 作者:zara(张子浩) 欢迎分享,但需在文章鲜明处留下原文地址. 在这一篇文章中我们希望使用Ope ...

  6. IdentityServer4【QuickStart】之利用OpenID Connect添加用户认证

    利用OpenID Connect添加用户认证 利用OpenID Connect添加用户认证 在这个示例中我们想要通过OpenID Connect协议将交互用户添加到我们的IdentityServer上 ...

  7. asp.net core系列 56 IS4使用OpenID Connect添加用户认证

    一.概述 在前二篇中讲到了客户端授权的二种方式: GrantTypes.ClientCredentials凭据授权和GrantTypes.ResourceOwnerPassword密码授权,都是OAu ...

  8. ASP.NET Core的身份认证框架IdentityServer4(9)-使用OpenID Connect添加用户认证

    OpenID Connect OpenID Connect 1.0是OAuth 2.0协议之上的一个简单的身份层. 它允许客户端基于授权服务器执行的身份验证来验证最终用户的身份,以及以可互操作和类似R ...

  9. IdentityServer4 中文文档 -11- (快速入门)添加基于 OpenID Connect 的用户认证

    IdentityServer4 中文文档 -11- (快速入门)添加基于 OpenID Connect 的用户认证 原文:http://docs.identityserver.io/en/releas ...

随机推荐

  1. 排序算法详解(java代码实现)

    ​ 排序算法大致分为内部排序和外部排序两种 内部排序:待排序的记录全部放到内存中进行排序,时间复杂度也就等于比较的次数 外部排序:数据量很大,内存无法容纳,需要对外存进行访问再排序,把若干段数据一次读 ...

  2. Linux内核浅入浅出

    公众号关注 「开源Linux」 回复「学习」,有我为您特别筛选的学习资料~ 01 前言 拥有超过1300万行的代码,Linux内核是世界上最大的开源项目之一,但是Linux内核是什么,它用于什么?且听 ...

  3. 无线:NB-IoT

    一. NB总体网络架构 NB-IoT端到端系统架构如下图所示: 终端:UE(User Equipment),通过空口连接到基站(eNodeB(evolved Node B , E-UTRAN 基站)) ...

  4. Git 不识别文件名字母大小写变化

    问题 今天为一个项目撰写持续构建计划,撰写 Jenkinsfile 之后进行构建时报错: [2022-05-23 16:54:21] unable to prepare context: unable ...

  5. docker安装nginx,配置SSL

    nginx安装 下载镜像并测试 1.docker pull nginx 2.docker images nginx 查看我们拉取到本地的nginx镜像IMAGE ID 3.首先测试下nginx镜像是否 ...

  6. java中的final与可变类型、不可变类型的关系

    如果你对final和不可变类型的概念与区别有疑问的话,可以打开这篇文章.希望我的解答可以帮到您! 1.不可变类型: 什么是可变类型,什么是不可变类型呢? 首先我们看一下下面的这行代码: String ...

  7. Python装饰器Decorators

    def hi(name="yasoob"): return "hi " + name print(hi()) # 我们甚至可以将一个函数赋值给一个变量,比如 g ...

  8. 回流&重绘

    浏览器加载解析页面:把HTML解析为DOM树,解析CSS生成CSSOM树,HTML DOM树和CSSOM树组合构建render树,首次触发回流和重绘后将页面结构信息发送给GPU进行绘制渲染. 回流:当 ...

  9. Linux离线包管理器RPM

    Linux离线包管理器RPM RPM 是RedHat Package Manager(RedHat软件包管理工具). 1.rpm常用参数介绍 查看rpm是否安装 rpm -q rpm包名 [root@ ...

  10. windows和linux系统下测试端口连通性的命令

    0. ping 1. telnet 2. ssh 3. curl 4. wget 5. tcping 6. 总结 本文地址: https://www.cnblogs.com/hchengmx/p/12 ...