Identity Server 4使用OpenID Connect添加用户身份验证(三)

一、说明

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

二、添加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项目

 Identity Server 4使用OpenID Connect添加用户身份验证(三)

四、环境配置

一、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 IdentityResources => new List
        {
          new IdentityResources.OpenId(),
          new IdentityResources.Profile()
        };

        // 基于OIDC添加测试用户
        public static List Users => new List() {

          new TestUser()
          {
              SubjectId="1",
              Username="admin",
              Password="123456777"
          }
        };

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

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

public static class SameSiteCookiesServiceCollectionExtensions
    {
        ///
        /// -1 defines the unspecified value, which tells ASPNET Core to NOT
        /// send the SameSite attribute. With ASPNET Core 3.1 the
        ///  enum will have a definition for
        /// Unspecified.

        ///
        private const SameSiteMode Unspecified = (SameSiteMode)(-1);

        ///
        /// Configures a cookie policy to properly set the SameSite attribute
        /// for Browsers that handle unknown values as Strict. Ensure that you
        /// add the
        /// into the pipeline before sending any cookies!

        ///
        ///
        /// 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
        ///
        /// The service collection to register  into.

        /// The modified .
        public static IServiceCollection ConfigureNonBreakingSameSiteCookies(this IServiceCollection services)
        {
            services.Configure(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;  // 增加这句
                }
            }
        }

        ///
        /// Checks if the UserAgent is known to interpret an unknown value as Strict.

        /// For those the  property should be
        /// set to .
        ///
        ///
        /// This code is taken from Microsoft:
        /// https://devblogs.microsoft.com/aspnet/upcoming-samesite-cookie-changes-in-asp-net-and-asp-net-core/
        ///
        /// The user agent string to check.

        /// Whether the specified user agent (browser) accepts SameSite=None or not.

        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、控制器增加如下方法

///
        /// 登出
        ///
        ///
        public IActionResult LogOut()
        {
            return SignOut("Cookies","oidc");
        }

        ///
        /// 模拟请求api
        ///
        ///
        public async Task 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页面配置

'@Url.Action("LogOut")'>登出    '@Url.Action("CallApi")'>模拟请求api

    用户信息
    @foreach (var claim in User.Claims)
    {
        @claim.Type
        @claim.Value
    }

    认证信息
    @foreach (var prop in (await Context.AuthenticateAsync()).Properties.Items)
    {
        @prop.Key
        @prop.Value
    }

五、项目运行效果

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

 Identity Server 4使用OpenID Connect添加用户身份验证(三)

 Identity Server 4使用OpenID Connect添加用户身份验证(三)

 Identity Server 4使用OpenID Connect添加用户身份验证(三)

 Identity Server 4使用OpenID Connect添加用户身份验证(三)

2、登出

 Identity Server 4使用OpenID Connect添加用户身份验证(三)

 Identity Server 4使用OpenID Connect添加用户身份验证(三)

3、模拟请求api

 Identity Server 4使用OpenID Connect添加用户身份验证(三)

 Identity Server 4使用OpenID Connect添加用户身份验证(三)

Original: https://www.cnblogs.com/sportsky/p/16468427.html
Author: SportSky
Title: Identity Server 4使用OpenID Connect添加用户身份验证(三)

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/608896/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 如你所见

    404. 抱歉,您访问的资源不存在。 可能是网址有误,或者对应的内容被删除,或者处于私有状态。 代码改变世界,联系邮箱 contact@cnblogs.com 园子的商业化努力-困…

    Linux 2023年6月6日
    066
  • 3.21 Linux PATH环境变量及作用(初学者必读)

    在讲解 PATH 环境变量之前,首先介绍一下 which 命令,它用于查找某个命令所在的绝对路径。例如: [root@localhost ~]# which rm /bin/rm …

    Linux 2023年6月7日
    077
  • supervisord 进程管理利器

    Supervisor概述 ​ supervisor是一个 Client/Server模式的系统,允许用户在类unix操作系统上监视和控制多个进程,或者可以说是多个程序。superv…

    Linux 2023年6月14日
    0100
  • Common LISP 命令大全

    书籍下载地址: Ansi Common Lisp 中文版|百度网盘 实用Common.Lisp编程 .pdf|百度网盘 LISP指令速查网站推荐: Simplified Commo…

    Linux 2023年6月6日
    0114
  • oracle 触发器trigger(主键自增长)

    触发器我们也可以认为是存储过程,是一种特殊的存储过程。 存储过程:有输入参数和输出参数,定义之后需要调用 触发器:没有输入参数和输出参数,定义之后无需调用,在 适当的时候会自动执行…

    Linux 2023年6月7日
    080
  • 惊了!修仙=编程??

    大家好,我是良许。 在我记忆中,我们接触到的所有编程书籍都是这样的: [En] As far as I can remember, all the programming book…

    Linux 2023年5月27日
    084
  • MacOS设置终端代理

    前言 国内的开发者或多或少都会因为网络而烦恼,因为一些特殊原因有时候网络不好的时候需要使用代理才能完成对应的操作。原来我一直都是使用斐讯路由器然后刷了梅林的固件,直接在路由器层面设…

    Linux 2023年6月14日
    081
  • ES查询区分大小写

    ES查询在默认的情况下是不区分大小写的,在5.0版本之后将 string类型拆分成两种新的数据类型, text用于全文搜索(模糊搜索), keyword用于关键字搜索(精确搜索)。…

    Linux 2023年6月8日
    099
  • 计算机系统实验

    实验三 一 实验目的 理解堆栈结构,利用缓冲区进行代码攻击 二 准备工作 配置实验环境(IDA、gcc),阅读实验指导书 三 实验过程 0x01第一关 首先理解堆栈的结构 /* 第…

    Linux 2023年6月8日
    088
  • 【Leetcode】63. 不同路径 II

    一个机器人位于一个 m x n网格的左上角 (起始点在下图中标记为 “Start” )。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在…

    Linux 2023年6月6日
    085
  • 一文搞懂 Redis 架构演化之路

    作者:ryetan,腾讯 CSIG 后台开发工程师 现如今 Redis 变得越来越流行,几乎在很多项目中都要被用到,不知道你在使用 Redis 时,有没有思考过,Redis 到底是…

    Linux 2023年5月28日
    095
  • 解决微信Windows客户端无法播放视频问题

    问题描述 我的Windows端微信版本是3.6.0,更新后点开视频,没有播放按钮出现,并且过一会就会卡死,并且整个微信程序崩掉。 问题解决 后来发现,是微信客户端的 播放器插件问题…

    Linux 2023年6月14日
    0353
  • 青春浙江微信平台如何退出?如何重新登录?微信如何清除浏览器缓存,如何清除浏览器cookies?

    青春浙江不能退出重新登录,有同学可能寻找解决方法,给大家贴出来:bug 解决办法:1. debugmm.qq.com/?forcex5=true 打开调试2. http://deb…

    Linux 2023年6月14日
    0116
  • Mysql数据库语言学习的路线

    对于我们数据库的学习,不管是测试人员还是开发人员以及我们的DBA来说重点都是SQL;但是我们的SQL可以分多少类型,学习重点又是在哪里呢,本文仅仅针对测试人员来展开说明: SQL:…

    Linux 2023年6月14日
    078
  • FastDFS安装和简介详细总结

    1、fastDFS简介 1 FastDFS是用c语言编写的一款开源的分布式文件系统。 2 FastDFS为互联网量身定制,充分考虑了冗余备份、负载均衡、线性扩容等机制,并注重高可用…

    Linux 2023年6月7日
    0114
  • WPF 应用启动过程同时启动多个 UI 线程且访问 ContentPresenter 可能让多个 UI 线程互等

    在应用启动过程里,除了主 UI 线程之外,如果还多启动了新的 UI 线程,且此新的 UI 线程碰到 ContentPresenter 类型,那么将可能存在让新的 UI 线程和主 U…

    Linux 2023年6月6日
    082
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球