.net 8.0的API集成到IdentityServer4里的记录

特别注意:

有的包在Nuget里找不到了,就直接把下面的引用写到文件里就行,可以不去Nuget里安装

1、引用的Nuget包

    <PackageReference Include="IdentityModel" Version="6.2.0" />
    <PackageReference Include="IdentityServer4" Version="4.1.2" />
    <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="3.1.32" />
    <PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="6.0.36" />
    <PackageReference Include="net6.identityserver4.accesstokenvalidation" Version="1.0.0" />
    <PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="6.36.0" />

2、Program.cs里的内容

using Serilog.Events;
using Serilog;
using System.Text;

var builder = WebApplication.CreateBuilder(args).Inject();

var app = builder.Build();

app.Run();

3、StartUp里的内容

using Furion;
using IdentityServer4;
using Microsoft.AspNetCore.HttpOverrides;
using Microsoft.IdentityModel.Tokens;
using System.ComponentModel;
using System.IdentityModel.Tokens.Jwt;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.IdentityModel.Logging;
using Microsoft.AspNetCore.Localization;
using System.Globalization;
using DrpApi.Database;

namespace DrpApi
{
    public class Startup : AppStartup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            IdentityModelEventSource.ShowPII = true;
            services.AddCorsAccessor();
            services.AddMemoryCache();
            services.AddSession();

            services.AddMvc(option =>
            {

            });
            services.AddDatabaseAccessor(options =>
            {
                // 配置默认数据库
                options.AddDbPool<DrpApiContext>();
                // 配置多个数据库,多个数据库必须指定数据库上下文定位器
                options.AddDbPool<DrpApiContext, SqlServerDbContextLocator>();
            });

            JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
            services.Configure<ForwardedHeadersOptions>(options =>
            {
                options.ForwardedHeaders =
                    ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
            });

            string authUrl = Furion.App.Configuration["ConfigInfo:IdentityServerUrl"];
            if (!authUrl.ToLower().StartsWith("http"))
            {
                authUrl = "http://" + authUrl;
            }
            string clientId = Furion.App.Configuration["ConfigInfo:IdentityClientId"];


            services.AddAuthentication("Bearer").AddJwtBearer("Bearer",
            options =>
            {
                options.Authority = authUrl;
                options.Audience = clientId;
                options.RequireHttpsMetadata = false;
                options.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateAudience = false
                };
                IdentityModelEventSource.ShowPII = true;
            })
           .AddOpenIdConnect("oidc", options =>
           {
               options.SignInScheme = "Cookies";
               options.Authority = authUrl;
               options.RequireHttpsMetadata = false;
               options.ClientId = clientId;
               options.ClientSecret = "1111A7E1-0C79-4A89-A3D6-A37998111000";
               options.ResponseType = "code id_token";
               options.Scope.Clear();
               options.Scope.Add("openid");
               options.Scope.Add("sid");
               options.Scope.Add("profile");
               options.Scope.Add("CommonAPI");
               options.Scope.Add(IdentityServerConstants.LocalApi.ScopeName);
               options.Scope.Add("IdentityServerApi");

               options.GetClaimsFromUserInfoEndpoint = true;

               options.SaveTokens = true;
               options.RequireHttpsMetadata = false;
               options.TokenValidationParameters = new TokenValidationParameters
               {
                   ValidateAudience = false
               };

               options.Events = new OpenIdConnectEvents()
               { //修复登录成功之后转向signin-oidc并报错的问题
                   OnRemoteFailure = ctx =>
                   {
                       //var message = ctx.Failure.Message;
                       ctx.Response.Redirect($"{ctx.Request.Scheme}://{ctx.Request.Host}");
                       ctx.Response.Body.WriteAsync(null);
                       return Task.CompletedTask;
                   }
               };

               //必须设置cookie signin-oidc 返回的cookie设置
               options.CorrelationCookie.SecurePolicy = CookieSecurePolicy.None;
               options.NonceCookie.SecurePolicy = CookieSecurePolicy.None;
               options.CorrelationCookie.SameSite = SameSiteMode.Unspecified;
               options.NonceCookie.SameSite = SameSiteMode.Unspecified;
           });
            services.AddAuthorization(options =>
            {
                options.AddPolicy("HybridPolicy", policy =>
                {
                    policy.RequireAuthenticatedUser();
                });
            });
            //想要解决跨域的问题
            services.AddCors(options => options.AddPolicy("CorsPolicy",
                        builder =>
                        {
                            builder.AllowAnyMethod()
                                .SetIsOriginAllowed(_ => true)
                                .AllowAnyHeader()
                                .AllowCredentials();
                        }));

            services.Configure<CookiePolicyOptions>(options =>
            {
                options.MinimumSameSitePolicy = SameSiteMode.Unspecified;
                options.OnAppendCookie = cookieContext =>
                    AuthenticationHelpers.CheckSameSite(cookieContext.Context, cookieContext.CookieOptions);
                options.OnDeleteCookie = cookieContext =>
                    AuthenticationHelpers.CheckSameSite(cookieContext.Context, cookieContext.CookieOptions);
            });

            services.AddConnections();

            services.AddControllersWithViews().AddJsonOptions(config =>
            {
                config.JsonSerializerOptions.PropertyNamingPolicy = null;
                config.JsonSerializerOptions.Converters.Add(new Furion.JsonSerialization.DateTimeJsonConverter("yyyy-MM-dd HH:mm:ss"));
            }).AddInjectWithUnifyResult();

            services.Configure<FormOptions>(options =>
            {
                options.ValueLengthLimit = 209715200;//200MB
            });
            var builder = services.AddRazorPages();
        }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
                app.UseHsts();
            }

            app.UseCors("CorsPolicy");

            app.UseStaticFiles();
            //app.UseSerilogRequestLogging();    // 必须在 UseStaticFiles 和 UseRouting 之间,,, 记录所有请求日志

            app.UseSession();

            app.UseCookiePolicy();

            app.UseRouting();



            app.UseCorsAccessor();

            app.UseAuthentication();
            app.UseAuthorization();
            app.UseInject();
            //确保UseRequestLocalization()在UseRouting()之后、UseEndpoints()之前调用。
            app.UseRequestLocalization();//app.UseRequestLocalization()中间件。这样整个应用程序会使用指定的文化设置,包括日期格式。

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller=Home}/{action=Index}/{id?}");

                endpoints.MapAreaControllerRoute(
                     name: "areas", "areas",
                     pattern: "{area:exists}/{controller=Home}/{action=Index}/{id?}");
            });
        }
        public static class AuthenticationHelpers
        {
            public static void CheckSameSite(HttpContext httpContext, CookieOptions options)
            {
                if (options.SameSite == SameSiteMode.None)
                {
                    var userAgent = httpContext.Request.Headers["User-Agent"].ToString();
                    if (!httpContext.Request.IsHttps || DisallowsSameSiteNone(userAgent))
                    {
                        // For .NET Core < 3.1 set SameSite = (SameSiteMode)(-1)
                        options.SameSite = SameSiteMode.Unspecified;
                    }
                    //else
                    //{
                    //    options.SameSite = SameSiteMode.Lax;  // 增加这句
                    //}
                }
            }

            public 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
                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.
                if (userAgent.Contains("Macintosh; Intel Mac OS X 10_14") &&
                    userAgent.Contains("Version/") && userAgent.Contains("Safari"))
                {
                    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.
                if (userAgent.Contains("Chrome/5") || userAgent.Contains("Chrome/6"))
                {
                    return true;
                }

                return false;
            }
        }
    }
}

4、Controller上的标记

namespace DrpApi.Controllers
{
    [Authorize]
    public class BaseController : ControllerBase
    {
    }
}

 

posted @ 2025-06-14 22:14  星星c#  阅读(57)  评论(0)    收藏  举报