【发布时间】: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