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)

大家都在看

  • Rprop 与 RMSprop 优化器

    https://www.cnblogs.com/setdong/p/16508415.html 1. Rprop 在 full-batch optimization 中, 一些梯度…

    Linux 2023年6月7日
    087
  • Go-goroutine

    进程和线程说明: (1)进程就是程序在操作系统中的一次执行过程,是系统进行资源分配和调度的基本单位。 (2)线程是进程的一个执行实例,是程序执行的最小单位,它是比进程更小的能独立运…

    Linux 2023年6月8日
    097
  • linux磁盘配额管理

    磁盘配额是一种磁盘空间的管理机制,使用磁盘配额可限制用户或组在某个特定文件系统中能使用的最大空间 1、查看内核是否支持磁盘配额 grep “CONFIG_QUOTA&#…

    Linux 2023年5月27日
    0102
  • Redis缓存查询时报字段无法识别问题-SerializationException: Could not read JSON: Unrecognized xxx

    报错信息: Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exce…

    Linux 2023年6月14日
    0102
  • SQL的执行流程

    1. SQL的语句结构 1.1 SQL92 语法 SELECT DISTINCT …,…,…(存在聚合函数) FROM …,…,… WHERE 多表的连接条…

    Linux 2023年6月14日
    089
  • 【MQTT】cJSON协议的安装和使用

    cJSON的使用 * – cJSON的简介 – + JSON 名称/值对 + JSON 数字 + JSON 对象 + JSON 数组 – cJS…

    Linux 2023年6月13日
    0114
  • 真·Android Zxing 扫码中文乱码解决

    Zxing3.2.1 之前遇到过Android Zxing扫码乱码的问题,网上搜了下解决了下。 今天又遇到了问题。 依然会乱码。 研究总结如下: Zxing 可以在Hints中添加…

    Linux 2023年6月13日
    083
  • python爬虫配置IP代理池(ProxyPool)

    关注我的公众号【靠谱杨的挨踢生活】回复 ProxyPool可以免费获取网盘链接。也可自行搜索下载:https://github.com/Python3WebSpider/Proxy…

    Linux 2023年6月14日
    0113
  • Timeout connecting to [localhost/127.0.0.1:9200]

    空服务启动时(或者压根没引入es相关jar包)报Timeout connecting to [localhost/127.0.0.1:9200]错误时,查看pom.xml中是否引用…

    Linux 2023年6月7日
    0147
  • JAVA设计模式-适配器模式

    JAVA设计模式-适配器模式 介绍 适配器模式是一种结构型模式,它主要解决接口之间的兼容问题。当我们需要使用某个类的接口时,但是这个类的接口目前并不符合我们使用需求,不能直接使用,…

    Linux 2023年6月6日
    0113
  • JuiceFS 新手必知 24 问

    JuiceFS 是一个创新性的软件产品,很多初次尝试的小伙伴对产品和用法感到很多疑惑,所以为了帮助大家快速理解并上手 JuiceFS,我们整理了24个关于 JuiceFS 经典的问…

    Linux 2023年6月14日
    0106
  • Powershell 测量命令执形时间

    powershell -Command (Measure-Command { "docker build –no-cache -f 2.2/Dockerfile 2.2…

    Linux 2023年5月28日
    083
  • Logback 日志框架

    Logback 是由 Log4j 创始人设计的又一个开源日志组件。作为流行的 Log4j 项目的继承者,在 log4j 1.x 停止的地方接手。其架构非常通用,可以在不同的情况下应…

    Linux 2023年6月8日
    0103
  • Spring事务(一)-事务配置

    事务是数据库操作最基本的单元,是逻辑上的一组操作,这一组操作在同一个会话中要么都执行成功,要么都失败,这也是事务的最基本特性–原子性。事务的作用是为了保证系统数据的正确…

    Linux 2023年6月6日
    094
  • 记一次从源码泄露到getshell(二)

    0x00 前言 文章所述漏洞已经提交至漏洞平台,且所有恶意操作均已复原 0x01 源码泄露 http://www.xxx.com.cn/www.zip 老规矩拿到源码先通关关键词找…

    Linux 2023年5月28日
    0107
  • Python环境安装

    一、下载地址: Python:Download Python | Python.org PyCharm:Download PyCharm: Python IDE for Profe…

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