如何解决身份服务器 4 - /signin-oidc
我们最近向 Azure 应用服务分别发布了两个 Web 应用。 Identity Server 4 应用程序和 .Net Core 3.1 Web 应用程序,它是 Identity Server 的客户端。通过 IIS/Visual Studio 在本地运行这些可以正常工作。我可以通过 Identity Server 登录我的客户端应用程序并重定向回来。
但是,将两个项目发布到 Azure 时,我收到以下错误消息。
Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectMessage..ctor(string json)
OpenIdConnectProtocolException:无法将令牌响应正文解析为 JSON。状态代码:500。内容类型:文本/纯文本 Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectHandler.RedeemAuthorizationCodeAsync(OpenIdConnectMessage tokenEndpointRequest)
异常:处理远程登录时遇到错误。 Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler.HandleRequestAsync()
我将在下面发布身份服务器和客户端项目的代码。任何有关该问题的帮助将不胜感激。
Identity.Startup:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.AddMvc(options =>
{
options.EnableEndpointRouting = false;
})
.AddNewtonsoftJson(options =>
{
options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
});
// Add Data GoCVContext
string GoCVDataConnectionString = EnvironmentHandler.WebDB;
services.AddDbContext<GoCVContext>(options => options.UseLazyLoadingProxies().UseSqlServer(GoCVDataConnectionString));
// Add Identity context
string IdentityConnectionString = EnvironmentHandler.IdentityDB;
var migrationsAssembly = typeof(Startup).GetTypeInfo().Assembly.GetName().Name;
services.AddDbContext<IdentityContext>(options =>
{
options.UseSqlServer(IdentityConnectionString,sql => sql.MigrationsAssembly(migrationsAssembly));
});
services.AddIdentity<ApplicationUser,IdentityRole>(options =>
{
// password config
options.Password.RequireDigit = true;
options.Password.RequiredLength = 8;
options.Password.RequireNonAlphanumeric = true;
options.Password.RequireUppercase = true;
options.Password.RequireLowercase = true;
// lockout config
options.Lockout.AllowedForNewUsers = true;
options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(10);
options.Lockout.MaxFailedAccessAttempts = 5;
// sign in options
options.SignIn.RequireConfirmedEmail = true;
// add custom class for email tokens
options.Tokens.EmailConfirmationTokenProvider = "CustomEmailConfirmation";
})
.AddEntityFrameworkStores<IdentityContext>()
.AddDefaultTokenProviders()
.AddTokenProvider<CustomEmailConfirmationTokenProvider<ApplicationUser>>("CustomEmailConfirmation");
// set lifespan of all tokens used
services.Configure<DataProtectionTokenProviderOptions>(options =>
{
options.TokenLifespan = TimeSpan.FromDays(1);
});
// set life span for email confirmation token
services.Configure<CustomEmailConfirmationTokenProviderOptions>(options =>
{
options.TokenLifespan = TimeSpan.FromDays(30);
});
var builder = services.AddIdentityServer(options =>
{
options.Events.RaiseErrorEvents = true;
options.Events.RaiseInformationEvents = true;
options.Events.RaiseFailureEvents = true;
options.Events.RaiseSuccessEvents = true;
options.UserInteraction.LoginUrl = "/Identity/Account/Login";
options.UserInteraction.LogoutUrl = "/Identity/Account/Logout";
options.Authentication = new AuthenticationOptions()
{
CookieLifetime = TimeSpan.FromHours(10),// ID server cookie timeout set to 10 hours
CookieSlidingExpiration = true
};
})
.AddConfigurationStore(options =>
{
options.ConfigureDbContext = b => b.UseSqlServer(IdentityConnectionString,sql => sql.MigrationsAssembly(migrationsAssembly));
})
.AddOperationalStore(options =>
{
options.ConfigureDbContext = b => b.UseSqlServer(IdentityConnectionString,sql => sql.MigrationsAssembly(migrationsAssembly));
options.EnableTokenCleanup = true;
})
.AddAspNetIdentity<ApplicationUser>()
.AddProfileService<ProfileService>();
services.AddLocalApiAuthentication();
services.AddAuthentication("Bearer")
.AddJwtBearer("Bearer",options =>
{
options.Authority = https://our_identity_server_url;
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateAudience = false
};
});
services.AddTransient<IProfileService,ProfileService>();
// not recommended for production - you need to store your key material somewhere secure
builder.AddDeveloperSigningCredential();
}
public void Configure(IApplicationBuilder app)
{
InitializeDatabase(app);
var forwardOptions = new ForwardedHeadersOptions
{
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto,RequireHeaderSymmetry = false
};
app.UseForwardedHeaders(forwardOptions);
if (Environment.IsDevelopment() || Environment.IsProduction())
{
app.UseDeveloperExceptionPage();
}
// uncomment if you want to add MVC
app.UseStaticFiles();
app.UseRouting();
app.UseIdentityServer();
app.UseAuthorization();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "areas",template: "{area:exists}/{controller=Home}/{action=Index}");
routes.MapRoute(
name: "default",template: "{controller=Home}/{action=Index}/{id?}");
});
}
客户端配置:
new Client
{
ClientId = "Our client Id",ClientName = "Our client name",ClientSecrets = { new Secret("oursecret".Sha256()) },AllowedGrantTypes = GrantTypes.CodeAndClientCredentials,AllowedCorsOrigins =
{
"https://our_client_app_url"
},RedirectUris = { "https://our_client_app_url/signin-oidc" },PostLogoutRedirectUris = { "https://our_client_app_url/signout-callback-oidc" },AllowedScopes = new List<string>
{
IdentityServerConstants.StandardScopes.OpenId,IdentityServerConstants.StandardScopes.Profile,IdentityServerConstants.StandardScopes.Email,JwtClaimTypes.Role
}
}
客户端网络应用。启动
public void ConfigureServices(IServiceCollection services)
{
EnvironmentHandler.Init(_configuration,environment);
services.AddControllersWithViews();
services.AddMvc().AddNewtonsoftJson();
services.AddMvc(options => options.EnableEndpointRouting = false);
services.AddSingleton<IActionContextAccessor,ActionContextAccessor>();
services.AddSingleton<IHttpContextAccessor,HttpContextAccessor>();
services.AddRazorPages();
services.Configure<RazorPagesOptions>
(options => options.RootDirectory = "/Views/Home");
string dbConnectionString = EnvironmentHandler.WebDB;
services.AddDbContext<GoCVContext>(options => options.UseLazyLoadingProxies().UseSqlServer(dbConnectionString));
JwtSecurityTokenHandler.DefaultMapInboundClaims = false;
services.AddAuthentication(options =>
{
options.DefaultScheme = "Cookies";
options.DefaultChallengeScheme = "oidc";
})
.AddCookie("Cookies")
.AddOpenIdConnect("oidc",options =>
{
options.Authority = "https://our_identity_server_url";
options.ClientId = "our client Id";
options.ClientSecret = "our secret";
options.ResponseType = "code";
options.SaveTokens = true;
options.GetClaimsFromUserInfoEndpoint = true;
options.Scope.Add("profile");
options.Scope.Add("roles");
options.ClaimActions.MapUniqueJsonKey("role","role");
options.TokenValidationParameters = new TokenValidationParameters
{
RoleClaimType = "role"
};
});
services.AddHttpContextAccessor();
}
public void Configure(IApplicationBuilder app,IWebHostEnvironment env)
{
using (var serviceScope = app.ApplicationServices.GetService<IServiceScopeFactory>().CreateScope())
{
var context = serviceScope.ServiceProvider.GetRequiredService<GoCVContext>();
context.Database.Migrate();
}
app.UseForwardedHeaders();
if (env.IsDevelopment() || env.IsProduction())
{
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
}
else
{
app.UseExceptionHandler("/Views/Shared/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.UseMvc(routes =>
{
routes.MapRoute(
name: "areas",template: "{area:exists}/{controller=Home}/{action=Index}");
routes.MapRoute(
name: "default",template: "{controller=Home}/{action=Index}/{id?}");
});
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。