IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 开发测试 -> net6 swagger与IdentityServer集成登录验证,完美解决调试、部署等问题 -> 正文阅读

[开发测试]net6 swagger与IdentityServer集成登录验证,完美解决调试、部署等问题

网上很多教程的结果是这样的,用postman获取token,再复制到下图value进行登录,这样的方式感觉有点呆。

理想的状态是跳到登录界面,实现集成登录验证,如图

自动跳转到登录界面

登录后再自动跳转到swgger

实现步骤

1、NuGet包添加Swashbuckle.AspNetCore

?

自定义鉴权中间件SetupAuthenticationMiddleware

using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using System;

namespace Kstopa.Extensions.Middlewares
{
    public static class SetupAuthenticationMiddleware
    {
        public static void AddAuthenticationSetup(this IServiceCollection services, IConfiguration configuration)
        {
            services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
            .AddJwtBearer(options =>
            {
                options.Authority = configuration["AuthServer:Authority"];
                options.RequireHttpsMetadata = Convert.ToBoolean(configuration["AuthServer:RequireHttpsMetadata"]);
                options.Audience = "KstopaAcs";
                options.TokenValidationParameters = new()
                {
                    ValidateAudience = false,
                    ValidateIssuerSigningKey = true,
                    ValidateIssuer = false,
                    LifetimeValidator = (before, expires, token, param) =>
                    {
                        return expires > DateTime.UtcNow;
                    }
                };
            });
 // API授权
            services.AddAuthorization(options =>
            {
                options.AddPolicy("ApiScope", policy =>
                {
                    policy.RequireAuthenticatedUser();
                    policy.RequireClaim("scope", "KstopaAcs");
                });
            });
        }
    }
}

?自定义SetupSwaggerGenMiddleware中间件

代码如下(ApiGroup与DescriptionAttribute类不建议到中间件里,ApiGroup是定义的分组)

关键代码:Flows使用Implicit类型,不要使用AuthorizationCode

using Microsoft.Extensions.DependencyInjection;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.Filters;
using Swashbuckle.AspNetCore.SwaggerGen;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;

namespace Kstopa.Extensions.Middlewares
{
public static class SetupSwaggerGenMiddleware
{
public static IServiceCollection AddSwaggerGenSetup(this IServiceCollection services, Action<SwaggerGenOptions> setupAction = null)
        {
            return services.AddSwaggerGen(delegate (SwaggerGenOptions options)
            {
                Func<OpenApiSchema> schemaFactory = () => new OpenApiSchema
                {
                    Type = "string",
                    Format = "binary"
                };
                setupAction?.Invoke(options);
            });
        }
public static IServiceCollection AddSwaggerGenWithOAuthSetup(this IServiceCollection services, string authority,
                Dictionary<string, string> scopes, Action<SwaggerGenOptions> setupAction = null)
        {
            return services.AddSwaggerGenSetup().AddSwaggerGen(delegate (SwaggerGenOptions options)
            {
                options.OperationFilter<SecurityRequirementsOperationFilter>();
                options.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme
                    {
                        Type = SecuritySchemeType.OAuth2,
                        Flows = new OpenApiOAuthFlows
                        {
                            Implicit = new OpenApiOAuthFlow
                            {
                                AuthorizationUrl = new Uri(authority + "connect/authorize"),
                                Scopes = scopes,
                                TokenUrl = new Uri(authority + "connect/token")
                            }
                        }
                    });
options.AddSecurityRequirement(new OpenApiSecurityRequirement
                {
                    {
                        new OpenApiSecurityScheme
                        {
                            Reference = new OpenApiReference
                            {
                                Type = ReferenceType.SecurityScheme,
                                Id = "oauth2"
                            }
                        },
                        Array.Empty<string>()
                    }
                });
                setupAction?.Invoke(options);
            });
        }
 /// <summary>
        /// 添加Xml注释
        /// </summary>
        /// <param name="options"></param>
        public static void AddXmlComments(this SwaggerGenOptions options)
        {
            var basePath = AppContext.BaseDirectory;

            #region Controller的注释
            {
                var xmlPath = Path.Combine(basePath, "Kstopa.HttpApi.Host.xml");
                if (File.Exists(xmlPath))
                {
                    options.IncludeXmlComments(xmlPath, true);//第二参数要设为true,默认为false
                }
            }
            #endregion

            #region Model的注释
            {
                var xmlModelPath = Path.Combine(basePath, "Kstopa.Model.xml");
                if (File.Exists(xmlModelPath))
                {
                    options.IncludeXmlComments(xmlModelPath);//第二参数默认为false,不用设
                    options.CustomSchemaIds(type => type.ToString());
                }
            }
            #endregion
        }
/// <summary>
        /// 按模块分组
        /// </summary>
        /// <param name="options"></param>
        public static void GroupByModule(this SwaggerGenOptions options)
        {
            #region 按模块分组显示
            {
                var fields = typeof(ApiGroup).GetFields().ToList();
                fields.ForEach(f =>
                {
                    var info = f.GetCustomAttributes(typeof(DescriptionAttribute), false)
                        .OfType<DescriptionAttribute>()
                        .FirstOrDefault();
                    options.SwaggerDoc($"{f.Name}", new OpenApiInfo
                    {
                        Title = $"{info?.Title} 接口文档-{RuntimeInformation.FrameworkDescription}",
                        Version = $"{info?.Version}",
                        Description = $"版本:{info?.Version} <br>{info?.Remark}"
                    });
                    options.OrderActionsBy(o => o.RelativePath);
                });
            }
#endregion

            #region 无分组归类显示
            {
                options.SwaggerDoc("无分组", new OpenApiInfo
                {
                    Title = $"接口文档——{RuntimeInformation.FrameworkDescription}",
                    Version = "v1",
                    Description = "Kstopa MES HTTP API v1"
                });
                options.DocInclusionPredicate((docName, description) =>
                {
                    if (docName.Equals("NoGroup"))
                    {
                        return string.IsNullOrEmpty(description.GroupName);
                    }
                    return description.GroupName == docName;
                });
            }
            #endregion
        }
    }
                    
      public class ApiGroup
    {
        [Description(Title = "系统通用", Remark = "导入(出)、定时任务、缓存、消息队列")]
        public static string Common_v1;

        [Description(Title = "系统框架", Remark = "组织、部门、用户、角色、权限、登录、枚举")]
        public static string Framework_v1;
    } 
public class DescriptionAttribute : Attribute
    {
        /// <summary>
        /// 标题
        /// </summary>
        public string Title { get; set; }

        /// <summary>
        /// 备注
        /// </summary>
        public string Remark { get; set; }

        /// <summary>
        /// 版本
        /// </summary>
        public string Version { get; set; } = "v1";
    }        
}

?在Program.cs使用中间件

 #region Authentication 鉴权设置
        {
            builder.Services.AddAuthenticationSetup(builder.Configuration);
            IdentityModelEventSource.ShowPII = true;//解决IDX10214: Audience validation failed. Audiences: '[PII is hidden]'错误
            builder.Services.AddHttpContextAccessorSetup();
        }
        #endregion
      builder.Services.AddCorsSetup(builder.Configuration);//跨域配置
        builder.Services.AddEndpointsApiExplorer();
        builder.Services.AddSwaggerGenWithOAuthSetup(
            builder.Configuration["AuthServer:Authority"],
            new Dictionary<string, string>
            {
                {"KstopaAcs", "KstopaAcs API"}
            },
            options =>
            {
                options.GroupByModule();
                options.AddXmlComments();
                options.CustomSchemaIds(type => type.FullName);
            });

配置文件代码

?"App": {
? ? "CorsOrigins": "https://*.KstopaAcs.com",
? ? "RegisterModule": "Kstopa.Service.dll",
? ? "StaticFilePath": "doc"
? },
? "AuthServer": {
? ? "Authority": "https://192.168.18.13:9081/",
? ? "RequireHttpsMetadata": false,
? ? "SwaggerClientId": "Kstopa",
? ? "SwaggerClientSecret": "xxxx"
? }

如下图

?

IdentityServer配置

RedirectUris为api服务地址+swagger/oauth2-redirect.html,如下图

可能会遇到的问题如下:

本机调试和服务器同时使用,只要在IdentityServer配置文件中添加多个RedirectUris即可

?跳到在登录界面录入帐号和密码后不跳转,必须使用https才可以,https需要证书请参考这里

使用 mkcert 解决 局域网IIS 网页 SSL 证书问题 - googlegis - 博客园

安装证书后,浏览器的安全锁如下图是正常的(客户端和服务器都要安装crt证书,按上图链接操作

?如果前端请求提示:IDX20803,一般是证书导致的问题(服务器没有安装证书)

证书加载代码:

 var cert = new X509Certificate2(builder.Configuration["cert:path"], builder.Configuration["cert:password"]);
    builder.Services.Configure<KestrelServerOptions>(options =>
    {
        options.ConfigureHttpsDefaults(c =>
        {
            c.ServerCertificate = cert;
        });
    }

?

如果有问题请加微信讨论:25489181

?

?

?

?

  开发测试 最新文章
pytest系列——allure之生成测试报告(Wind
某大厂软件测试岗一面笔试题+二面问答题面试
iperf 学习笔记
关于Python中使用selenium八大定位方法
【软件测试】为什么提升不了?8年测试总结再
软件测试复习
PHP笔记-Smarty模板引擎的使用
C++Test使用入门
【Java】单元测试
Net core 3.x 获取客户端地址
上一篇文章      下一篇文章      查看所有文章
加:2022-03-06 13:28:06  更:2022-03-06 13:29:26 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/18 2:32:46-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码