【问题标题】:Using Duende Identity Server behind a Nginx Reverse Proxy在 Nginx 反向代理后面使用 Duende Identity Server
【发布时间】:2023-01-20 15:01:54
【问题描述】:

概述

我有一个微服务解决方案,其中包括 Blazor 应用程序、Web API 服务和 Duende Identity Server。另外,我使用 Nginx 作为访问服务的反向代理。当我配置 Blazor App 直接使用 Duende 进行身份验证时,它工作正常,但是当我想在它们之间添加 Nginx 时,它不起作用。我按照IdentityServer/IdentityServer4#1623(评论)解决了这个问题,但是我没有成功。下面,我描述了服务配置以及到目前为止我在做什么:

Nginx

Nginx.conf 配置如下:

worker_processes  1;
events {
     worker_connections  1024;
}
http {
     include       mime.types;
     default_type  application/octet-stream;
     log_format  main  '[$time_local]-status :[$status] - $remote_addr - $host - UriAddr: [$request_uri] - XFF : ["$http_x_forwarded_for"] '
                  '- BodyByteSent : [$body_bytes_sent] "$http_referer" '
                  '"$request"'; #"$http_user_agent"
     access_log  logs/access.log  main;
     sendfile        on; 
     keepalive_timeout  300;   
     include nginx_http.conf;  
}

并且 nginx_http.conf 已经配置如下:

    server {
    listen       80;
    server_name  localhost;
    server_tokens off;

    gzip on;
    gzip_buffers      16 8k;
    gzip_comp_level   4;
    gzip_http_version 1.0;
    gzip_min_length   1280;
    gzip_types        *;
    gzip_vary         on;    
    gzip_disable msie6;
    charset UTF-8;
    include nginx_access_control.conf;
    location / {
        proxy_set_header   X-Forwarded-For $remote_addr;
        proxy_set_header   X-Real-IP $remote_addr;
        proxy_set_header   Host $http_host;
        #proxy_set_header Referer $http_referer;

        proxy_pass         https://127.0.0.1:5001/;
    }
location /Identity/ {
        proxy_set_header   Host $host;
        proxy_set_header   X-Real-IP $remote_addr;
        proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;

        proxy_pass         http://127.0.0.1:12000/;
    }

}

杜安德身份服务

此服务在 https://localhost:12001/ 和 HTTP://localhost:12000/ 上运行,使用 dotnet 6 身份服务器配置如下:

 builder.Services.AddIdentityServer(options =>
{
    options.IssuerUri = "http://localhost/Identity/";
})
 .AddDeveloperSigningCredential()
.AddInMemoryClients(new List<Client>
{
    new Client
    {
        ClientName = "Web User",
        ClientId = "web",/*"D2B8B5EC-9766-40B9-9D95-077B54245E6E",*/
        ClientSecrets= {new Secret("123456".Sha256())},
        AllowedGrantTypes = GrantTypes.Code,
        // RedirectUris={"https://localhost:5001/signin-oidc"},
        RedirectUris={"http://localhost/signin-oidc"},
        PostLogoutRedirectUris={ "http://localhost/signout-callback-oidc" },
        AllowedScopes=
        {
            "openid",
            "profile"
        }
    }
}).AddInMemoryIdentityResources(new List<IdentityResource>
{
    new IdentityResources.OpenId(),
    new IdentityResources.Profile(),
})
.AddInMemoryApiScopes(new List<ApiScope>
{
    new ApiScope("Management.fullaccess")
})
.AddInMemoryApiResources(new List<ApiResource>
{
    new ApiResource("Management","Management Service")
    {
        Scopes = { "Management.fullaccess" }      
    }
})
.AddAspNetIdentity<User>();

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();
app.UseIdentityServer();
app.UseAuthorization();

app.MapRazorPages();
app.MapControllers();
app.Run();

Blazor 应用程序

此服务在 https://localhost:5001/ 和 HTTP://localhost:5000/ 上运行,使用 dotnet 5 启动配置如下:

        public void ConfigureServices(IServiceCollection services)
    {
        var blazorSevice = services.AddControllersWithViews();

        services.Configure<ForwardedHeadersOptions>(options =>
        {
            options.ForwardedHeaders =
                ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
        });
        if (environment.IsDevelopment())
        {
            blazorSevice.AddRazorRuntimeCompilation();
        }
        services.AddRazorPages();
        services.AddServerSideBlazor(o => o.DetailedErrors = true);
        services.AddAuthentication(p =>
            {
                p.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                p.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
            }).AddCookie(CookieAuthenticationDefaults.AuthenticationScheme)
            .AddOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, options =>
            {
                options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                options.Authority = "http://localhost/Identity";//"http://localhost:12000";
                options.MetadataAddress = "http://localhost/Identity/.well-known/openid-configuration";
                options.ClientId = "web";
                options.ClientSecret = "123456";
                options.ResponseType = "code";
                options.GetClaimsFromUserInfoEndpoint = true;
                options.Scope.Add("profile");
                options.Scope.Add("openid");
                options.SaveTokens = true;
                options.RequireHttpsMetadata = false;
                
            });

        services.AddTelerikBlazor();
    }
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        app.UseForwardedHeaders();

        app.Use(async (httpcontext, next) =>
        {
            await next();
            string location = httpcontext.Response.Headers[Microsoft.Net.Http.Headers.HeaderNames.Location];

            if ((httpcontext.Response.StatusCode == StatusCodes.Status302Found
                || httpcontext.Response.StatusCode == StatusCodes.Status307TemporaryRedirect)
                && location != "https://localhost:5001/signin-oidc"
                && location != "https://localhost:5001/")
            {
                location = location.Replace("https","http")
                    .Replace("://localhost:5001/", "://localhost/Identity/");
                httpcontext.Response.Headers[Microsoft.Net.Http.Headers.HeaderNames.Location] = location;
            }
            if (httpcontext.Response.StatusCode == StatusCodes.Status302Found
                || httpcontext.Response.StatusCode == StatusCodes.Status307TemporaryRedirect)
            {
                if (location != "https://localhost:5001/" 
                    && location != "https://localhost:5001/signin-oidc" 
                    && !location.Contains("://localhost/Identity/"))
                {
                    location = location.Replace("%3A5001", "")
                        .Replace("://localhost/", "://localhost/Identity/")
                        .Replace("://localhost:12001/", "://localhost/Identity/");
                    httpcontext.Response.Headers[Microsoft.Net.Http.Headers.HeaderNames.Location] = location;
                }
            }
        });
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Error");
            // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
            app.UseHsts();
        }

        app.UseHttpsRedirection();
        app.UseStaticFiles();

        app.UseRouting();

        app.UseAuthentication();
        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapDefaultControllerRoute();
            endpoints.MapControllers();
        
            endpoints.MapBlazorHub(option =>
                option.Transports = HttpTransportType.LongPolling);
            endpoints.MapFallbackToPage("/_Host");
        });
    }

在上面的代码中,我尝试使用中间件更改 HTTP 响应位置以重定向属于 Duende Identity Server 的请求,但我认为这不是一种常见的方法! 使用上面显示的所有配置,现在,当我运行 blazor 应用程序时,它会重定向到 Duende 服务中的登录页面,但是当我单击登录按钮时,它会重定向到 /signin-oidc 路由并显示错误:

似乎在重定向到 /signin-oidc 后,blazor 应用程序尝试从 Duende 服务中的 /connect/token 获取令牌,但它返回错误。 我搜索了类似的解决方案,但找不到任何东西!谁能帮我?

【问题讨论】:

    标签: nginx blazor microservices


    【解决方案1】:

    最可能的问题在于缺少 x-forwarded-for 标头。你需要使用这些标头来告诉 duende 你有一个反向代理的事实。

    您可以通过在管道的开头添加以下中间件来添加标头:

    app.UseForwardedHeaders(new ForwardedHeadersOptions
    {
        ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-05
      • 1970-01-01
      • 1970-01-01
      • 2014-07-22
      相关资源
      最近更新 更多