一、说明

基于上一篇文章中的代码进行继续延伸,只需要小小的改动即可,不明白的地方可以先看看本人上一篇文章及源码 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. SoftPool:基于Softmax加权的池化操作 | 2021新文

    SoftPool使用softmax进行加权池化,能够保持特征的表达性并且是可微操作.从性能和准确率来看,SoftPool是目前的常规池化方法的一个不错的替代品   来源:晓飞的算法工程笔记 公众号 论 ...

  2. 【CSAPP】Attack Lab实验笔记

    attacklab这节玩的是利用一个字符串进行缓冲区溢出漏洞攻击,就小时候想象中黑客干的事儿. 做题的时候好几次感叹这些人的脑洞,"这都可以攻击?还能这么注入?这还可能借力打力?" ...

  3. 谁动了我的主机? 之活用History命令

    点击上方"开源Linux",选择"设为星标" 回复"学习"获取独家整理的学习资料! Linux系统下可通过history命令查看用户所有的历 ...

  4. RocketMq 完整部署

    目录 RocketMq 部署 环境 物理机部署 自定义日志目录 自定义参数和数据存放位置 服务启动 启动name server 启动broker 关停服务 尝试发送消息 常见报错 部署 rockerm ...

  5. 98. 验证二叉搜索树 前序遍历解法以及后续遍历解法(go语言)

    leetcode题目 98. 验证二叉搜索树 前序遍历 最简洁的答案版本,由于先判断的是根节点,所以直接判断当前root的值v,是否满足大于左子树最大,小于右子树最小,然后再遍历左子树,右子树是否是这 ...

  6. linux篇-centos7搭建apache服务器(亲测可用)

    1安装apache yum install httpd httpd-devel -y 2开启服务器 systemctl start httpd.service 3开机自启 systemctl enab ...

  7. 好客租房21-react组件的两种创建方式(函数组件)

    1使用函数创建组件 函数组件:使用js的函数或者箭头函数创建的组件 约定1:函数组件名称必须以 开头 约定2:函数组件必须有返回值 表示该组件的结构 如果返回值为null 表示不渲染任何内容 2.1使 ...

  8. linux系统下文件误删除该如何恢复?

    一.linux误删除数据的场景 在实际的工作中,朋友们可能会将linux服务器上的文件不小心误删除掉了.而且越是资历老的工程师越容易犯这样的错误,敲代码的速度也是够快,啪啪rm -rf一个回车,然后就 ...

  9. ASP.NET MVC 处理管线模型

    MVC管道整体处理模型 1.在ASP.NET MVC处理管线中的第一站就是路由模块.当请求到达路由模块后,MVC框架就会根据Route Table中配置的路由模板来匹配当前请求以获得对应的contro ...

  10. 《C Primer Plus》第六版笔记--7~10章

    目录 第七章 C控制语句:分支和跳转 第八章 字符输入/输出和输入验证 第九章 函数 第十章 数组和指针 第七章 C控制语句:分支和跳转 if else 用法 if (expression) //ex ...