C# IdentityServer4不带UI的Windows身份验证
我希望能够使用IdentityServer4作为使用Windows身份验证的应用程序的STS。我的大多数应用程序没有UI组件(它们只是ASP.NET核心API)。通过遵循指南并使用“is4inmem”身份服务器模板,我已经能够使用MVC(UI)客户端获得我的IdentityServer4 Windows身份验证。我使用的MVC客户端是示例客户端。我现在正在尝试设置我的api客户端。我的所有应用程序都使用kestrel托管,下面是IIS,以便启用Windows身份验证。下面是我的api客户端的Startup.cs的样子,我相信这就是问题所在C# IdentityServer4不带UI的Windows身份验证,c#,asp.net-mvc,asp.net-core,asp.net-web-api,identityserver4,C#,Asp.net Mvc,Asp.net Core,Asp.net Web Api,Identityserver4,我希望能够使用IdentityServer4作为使用Windows身份验证的应用程序的STS。我的大多数应用程序没有UI组件(它们只是ASP.NET核心API)。通过遵循指南并使用“is4inmem”身份服务器模板,我已经能够使用MVC(UI)客户端获得我的IdentityServer4 Windows身份验证。我使用的MVC客户端是示例客户端。我现在正在尝试设置我的api客户端。我的所有应用程序都使用kestrel托管,下面是IIS,以便启用Windows身份验证。下面是我的api客户端的St
public class Startup
{
public IWebHostEnvironment HostingEnvironment { get; private set; }
public IConfiguration Configuration { get; }
public Startup(IConfiguration configuration, IWebHostEnvironment env)
{
HostingEnvironment = env;
Configuration = configuration;
}
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddAuthentication("token")
.AddJwtBearer("token", options => {
options.Authority = "https://localhost:44353";
options.TokenValidationParameters.ValidateAudience = false;
options.TokenValidationParameters.ValidTypes = new[] { "at+jwt" };
});
services.AddAuthorization(options => {
options.AddPolicy("scope", policy => {
policy.AddAuthenticationSchemes("token")
.RequireAuthenticatedUser()
.RequireClaim("scope", "api1");
});
});
AppServSettings.WebHostEnvironment = HostingEnvironment;
var appSettingsSection = Configuration.GetSection("appSettings");
var connectionStringsSection = Configuration.GetSection("appSettings");
services.Configure<AppSettings>(appSettingsSection)
.Configure<ConnectionStrings>(connectionStringsSection);
services.AddControllersWithViews(options => {
options.InputFormatters.Add(new ProtobufInputFormatter());
options.OutputFormatters.Add(new ProtobufOutputFormatter());
});
var appSettingsOptions = new AppSettings();
appSettingsSection.Bind(appSettingsOptions);
var connectionStringsOptions = new ConnectionStrings();
connectionStringsSection.Bind(connectionStringsOptions);
AppServSettings.AppSettings = new AppEnvSettings(Options.Create<AppSettings>(appSettingsOptions), Options.Create<ConnectionStrings>(connectionStringsOptions));
AppServ.Preload();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app)
{
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(
endpoints => endpoints.MapControllers()
);
}
}
我试图使用的客户端是使用NTLM授权方案的Postman。此外,我还设置了cookies“.AspNetCore.Antiforgery.WxKm21GkYM0”和“idsrv.external”。我目前也在使用NuGet的IdentityServer4版本3.1.3
下面是我和邮递员一起发送的请求,打开了body标签。如您所见,我设置了授权类型、范围、客户机id和客户机机密
请发布您的客户端代码(尝试使用客户端凭据工作流获取令牌的应用程序。此外,如果您使用的是IdentityServer 4的v4.0x,则还必须定义APiscope。我更新了我的帖子,指定了客户端和IdentityServer的版本。通过设计,Api将返回401 a)因为令牌无效或丢失,B)因为没有可用的UI。当您查看调用Api的示例时,您将看到到IdentityServer登录页面的重定向是由客户端初始化的。因此,当客户端从api接收401时,应该由客户端启动用户登录。
public static class Config
{
public static IEnumerable<IdentityResource> Ids =>
new IdentityResource[]
{
new IdentityResources.OpenId(),
new IdentityResources.Profile(),
new IdentityResources.Email(),
new IdentityResources.Address(),
};
public static IEnumerable<ApiResource> Apis =>
new ApiResource[]
{
// new ApiResource("api1", "My API #1")
new ApiResource("api1", "My API", new[] { JwtClaimTypes.Subject, JwtClaimTypes.Email, JwtClaimTypes.Address, "upn_custom"})
};
public static IEnumerable<Client> Clients =>
new Client[]
{
// client credentials flow client
new Client
{
ClientId = "identity.server",
ClientName = "Identity Server Client",
AllowedGrantTypes = GrantTypes.ClientCredentials,
AlwaysIncludeUserClaimsInIdToken = true,
ClientSecrets = { new Secret("secret".Sha256()) },
AllowedScopes = { "openid", "profile", "email", "address", "api1", "upn_custom" }
},
// MVC client using code flow + pkce
new Client
{
//ClientId = "mvc",
ClientId = "mvc.code",
ClientName = "MVC Client",
// Note
AlwaysIncludeUserClaimsInIdToken = true,
AllowedGrantTypes = GrantTypes.CodeAndClientCredentials,
//RequirePkce = true,
RequirePkce = false,
//ClientSecrets = { new Secret("49C1A7E1-0C79-4A89-A3D6-A37998FB86B0".Sha256()) },
ClientSecrets = { new Secret("secret".Sha256()) },
//RedirectUris = { "https://localhost:5003/signin-oidc" },
RedirectUris = { "https://localhost:5003/signin-oidc" },
FrontChannelLogoutUri = "https://localhost:5003/signout-oidc",
PostLogoutRedirectUris = { "https://localhost:5003/signout-callback-oidc" },
AllowOfflineAccess = true,
AllowedScopes = { "openid", "profile", "email", "address", "api1", "upn_custom" }
},
// MVC client using code flow + pkce
new Client
{
//ClientId = "mvc",
ClientId = "ptp.appserv",
ClientName = "PTP AppServ",
// Note
AlwaysIncludeUserClaimsInIdToken = true,
AllowedGrantTypes = GrantTypes.CodeAndClientCredentials,
//RequirePkce = true,
RequirePkce = false,
//ClientSecrets = { new Secret("49C1A7E1-0C79-4A89-A3D6-A37998FB86B0".Sha256()) },
ClientSecrets = { new Secret("secret".Sha256()) },
//RedirectUris = { "https://localhost:30001/signin-oidc" },
RedirectUris = { "https://localhost:30001/signin-oidc" },
FrontChannelLogoutUri = "https://localhost:30001/signout-oidc",
PostLogoutRedirectUris = { "https://localhost:30001/signout-callback-oidc" },
AllowOfflineAccess = true,
AllowedScopes = { "openid", "profile", "email", "address", "api1", "upn_custom" }
},
// MCW Appserver
new Client
{
//ClientId = "mvc",
ClientId = "mcw.appserver",
ClientName = "MCW AppServer",
// Note
AlwaysIncludeUserClaimsInIdToken = true,
AllowedGrantTypes = GrantTypes.ClientCredentials,
RequirePkce = true,
//RequirePkce = false,
//ClientSecrets = { new Secret("49C1A7E1-0C79-4A89-A3D6-A37998FB86B0".Sha256()) },
ClientSecrets = { new Secret("secret".Sha256()) },
//RedirectUris = { "http://localhost:16835/signin-oidc" },
//RedirectUris = { "https://localhost:16385/signin-oidc" },
//FrontChannelLogoutUri = "https://localhost:16835/signout-oidc",
//PostLogoutRedirectUris = { "https://localhost:16835/signout-callback-oidc" },
AllowOfflineAccess = true,
AllowedScopes = { "openid", "profile", "email", "address", "api1", "upn_custom" }
},
// SPA client using code flow + pkce
new Client
{
ClientId = "spa",
ClientName = "SPA Client",
ClientUri = "http://identityserver.io",
AllowedGrantTypes = GrantTypes.Code,
RequirePkce = true,
RequireClientSecret = false,
RedirectUris =
{
"http://localhost:5002/index.html",
"http://localhost:5002/callback.html",
"http://localhost:5002/silent.html",
"http://localhost:5002/popup.html",
},
PostLogoutRedirectUris = { "http://localhost:5002/index.html" },
AllowedCorsOrigins = { "http://localhost:5002" },
AllowedScopes = { "openid", "profile", "api1" }
}
};
}
[Route("api/[controller]")]
[Authorize]
[ApiController]
public class IdentityController : ControllerBase
{
public IActionResult Get()
{
return new JsonResult(from c in User.Claims select new { c.Type, c.Value });
}
}