C# IdentityServer4-验证令牌失败
你好 今天我从IdentityServer4开始,我想用IdentityServer4和i ConsoleClient(后来是Xamarin客户端)启动一个ASP.NET Core 2.2站点。但我很绝望,它不起作用。希望有人能帮助我 当我尝试从ConsoleClient调用web api控制器到ASP.NET站点时,出现以下错误。 致意C# IdentityServer4-验证令牌失败,c#,asp.net,.net,asp.net-mvc,identityserver4,C#,Asp.net,.net,Asp.net Mvc,Identityserver4,你好 今天我从IdentityServer4开始,我想用IdentityServer4和i ConsoleClient(后来是Xamarin客户端)启动一个ASP.NET Core 2.2站点。但我很绝望,它不起作用。希望有人能帮助我 当我尝试从ConsoleClient调用web api控制器到ASP.NET站点时,出现以下错误。 致意 [02:50:17 Information] Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerH
[02:50:17 Information] Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler
Failed to validate the token.
Microsoft.IdentityModel.Tokens.SecurityTokenInvalidAudienceException: IDX10214: Audience validation failed. Audiences: '[PII is hidden]'. Did not match: validationParameters.ValidAudience: '[PII is hidden]' or validationParameters.ValidAudiences: '[PII is hidden]'.
at Microsoft.IdentityModel.Tokens.Validators.ValidateAudience(IEnumerable`1 audiences, SecurityToken securityToken, TokenValidationParameters validationParameters) in C:\agent2\_work\56\s\src\Microsoft.IdentityModel.Tokens\Validators.cs:line 108
at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateTokenPayload(JwtSecurityToken jwtToken, TokenValidationParameters validationParameters) in C:\agent2\_work\56\s\src\System.IdentityModel.Tokens.Jwt\JwtSecurityTokenHandler.cs:line 737
at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateToken(String token, TokenValidationParameters validationParameters, SecurityToken& validatedToken) in C:\agent2\_work\56\s\src\System.IdentityModel.Tokens.Jwt\JwtSecurityTokenHandler.cs:line 719
at Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler.HandleAuthenticateAsync()
[02:50:17 Information] Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler
BearerIdentityServerAuthenticationJwt was not authenticated. Failure message: IDX10214: Audience validation failed. Audiences: '[PII is hidden]'. Did not match: validationParameters.ValidAudience: '[PII is hidden]' or validationParameters.ValidAudiences: '[PII is hidden]'.
[02:50:17 Information] IdentityServer4.AccessTokenValidation.IdentityServerAuthenticationHandler
Bearer was not authenticated. Failure message: IDX10214: Audience validation failed. Audiences: '[PII is hidden]'. Did not match: validationParameters.ValidAudience: '[PII is hidden]' or validationParameters.ValidAudiences: '[PII is hidden]'.
[02:50:17 Information] Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler
AuthenticationScheme: BearerIdentityServerAuthenticationJwt was challenged.
[02:50:17 Information] IdentityServer4.AccessTokenValidation.IdentityServerAuthenticationHandler
AuthenticationScheme: Bearer was challenged.
这是我的Config.cs:
namespace IdentityServer
{
public static class Config
{
public static IEnumerable<IdentityResource> GetIdentityResources()
{
return new IdentityResource[]
{
new IdentityResources.OpenId()
};
}
public static List<TestUser> GetUsers()
{
return new List<TestUser>
{
new TestUser
{
SubjectId = "1",
Username = "alice",
Password = "password"
},
new TestUser
{
SubjectId = "2",
Username = "bob",
Password = "bob"
}
};
}
public static IEnumerable<ApiResource> GetApis()
{
return new List<ApiResource>
{
new ApiResource("api1", "My API")
};
}
public static IEnumerable<Client> GetClients()
{
return new List<Client>
{
new Client
{
ClientId = "client",
RequireConsent = false,
AllowAccessTokensViaBrowser = true,
// no interactive user, use the clientid/secret for authentication
AllowedGrantTypes = GrantTypes.ResourceOwnerPasswordAndClientCredentials,
// secret for authentication
ClientSecrets =
{
new Secret("secret".Sha256())
},
// scopes that client has access to
AllowedScopes = { "api1" }
}
};
}
}
}
public class Startup
{
public IHostingEnvironment Environment { get; }
public Startup(IHostingEnvironment environment)
{
Environment = environment;
}
public void ConfigureServices(IServiceCollection services)
{
services
.AddMvcCore()
.AddJsonFormatters()
.AddAuthorization();
services.AddIdentityServer(options =>
{
options.Events.RaiseErrorEvents = true;
options.Events.RaiseInformationEvents = true;
options.Events.RaiseFailureEvents = true;
options.Events.RaiseSuccessEvents = true;
options.IssuerUri = "http://localhost:5000";
}
)
.AddInMemoryClients(Config.GetClients())
.AddInMemoryApiResources(Config.GetApis())
.AddInMemoryIdentityResources(Config.GetIdentityResources())
.AddDeveloperSigningCredential()
.AddJwtBearerClientAuthentication()
.AddTestUsers(Config.GetUsers());
services.AddAuthentication()
.AddIdentityServerAuthentication(o =>
{
o.Authority = "http://localhost:5000";
o.ApiName = "client";
o.ApiSecret = "secret";
o.EnableCaching = true;
o.RequireHttpsMetadata = false;
o.SaveToken = true;
}).AddCookie();
services.AddCors();
services.AddMvc();
}
public void Configure(IApplicationBuilder app)
{
app.UseCors(policy =>
{
policy.WithOrigins(
"http://localhost:5000",
"http://localhost:5001");
policy.AllowAnyHeader();
policy.AllowAnyMethod();
policy.WithExposedHeaders("WWW-Authenticate");
});
if (Environment.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseStaticFiles();
app.UseIdentityServer();
app.UseMvcWithDefaultRoute();
}
}
[Route("api/identity")]
[Authorize(AuthenticationSchemes = IdentityServerAuthenticationDefaults.AuthenticationScheme)]
public class IdentityController : ControllerBase
{
[HttpGet]
public IActionResult Get()
{
//return new JsonResult(from c in User.Claims select new { c.Type, c.Value });
return new OkObjectResult("OK");
}
}
class Program
{
static HttpClient _tokenClient = new HttpClient();
static DiscoveryCache _cache = new DiscoveryCache("http://localhost:5000");
static async Task Main()
{
Console.Title = "Console ResourceOwner Flow UserInfo";
var response = await RequestTokenAsync();
response.Show();
await CallServiceAsync(response.AccessToken);
}
static async Task CallServiceAsync(string token)
{
var baseAddress = "http://localhost:5000";
var client = new HttpClient
{
BaseAddress = new Uri(baseAddress)
};
client.SetBearerToken(token);
var response = await client.GetStringAsync("api/identity");
}
static async Task<TokenResponse> RequestTokenAsync()
{
var disco = await _cache.GetAsync();
if (disco.IsError) throw new Exception(disco.Error);
var response = await _tokenClient.RequestPasswordTokenAsync(new PasswordTokenRequest
{
Address = disco.TokenEndpoint,
ClientId = "client",
ClientSecret = "secret",
UserName = "bob",
Password = "bob",
Scope = "api1"
});
if (response.IsError) throw new Exception(response.Error);
return response;
}
}
示例Auth。控制器:
namespace IdentityServer
{
public static class Config
{
public static IEnumerable<IdentityResource> GetIdentityResources()
{
return new IdentityResource[]
{
new IdentityResources.OpenId()
};
}
public static List<TestUser> GetUsers()
{
return new List<TestUser>
{
new TestUser
{
SubjectId = "1",
Username = "alice",
Password = "password"
},
new TestUser
{
SubjectId = "2",
Username = "bob",
Password = "bob"
}
};
}
public static IEnumerable<ApiResource> GetApis()
{
return new List<ApiResource>
{
new ApiResource("api1", "My API")
};
}
public static IEnumerable<Client> GetClients()
{
return new List<Client>
{
new Client
{
ClientId = "client",
RequireConsent = false,
AllowAccessTokensViaBrowser = true,
// no interactive user, use the clientid/secret for authentication
AllowedGrantTypes = GrantTypes.ResourceOwnerPasswordAndClientCredentials,
// secret for authentication
ClientSecrets =
{
new Secret("secret".Sha256())
},
// scopes that client has access to
AllowedScopes = { "api1" }
}
};
}
}
}
public class Startup
{
public IHostingEnvironment Environment { get; }
public Startup(IHostingEnvironment environment)
{
Environment = environment;
}
public void ConfigureServices(IServiceCollection services)
{
services
.AddMvcCore()
.AddJsonFormatters()
.AddAuthorization();
services.AddIdentityServer(options =>
{
options.Events.RaiseErrorEvents = true;
options.Events.RaiseInformationEvents = true;
options.Events.RaiseFailureEvents = true;
options.Events.RaiseSuccessEvents = true;
options.IssuerUri = "http://localhost:5000";
}
)
.AddInMemoryClients(Config.GetClients())
.AddInMemoryApiResources(Config.GetApis())
.AddInMemoryIdentityResources(Config.GetIdentityResources())
.AddDeveloperSigningCredential()
.AddJwtBearerClientAuthentication()
.AddTestUsers(Config.GetUsers());
services.AddAuthentication()
.AddIdentityServerAuthentication(o =>
{
o.Authority = "http://localhost:5000";
o.ApiName = "client";
o.ApiSecret = "secret";
o.EnableCaching = true;
o.RequireHttpsMetadata = false;
o.SaveToken = true;
}).AddCookie();
services.AddCors();
services.AddMvc();
}
public void Configure(IApplicationBuilder app)
{
app.UseCors(policy =>
{
policy.WithOrigins(
"http://localhost:5000",
"http://localhost:5001");
policy.AllowAnyHeader();
policy.AllowAnyMethod();
policy.WithExposedHeaders("WWW-Authenticate");
});
if (Environment.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseStaticFiles();
app.UseIdentityServer();
app.UseMvcWithDefaultRoute();
}
}
[Route("api/identity")]
[Authorize(AuthenticationSchemes = IdentityServerAuthenticationDefaults.AuthenticationScheme)]
public class IdentityController : ControllerBase
{
[HttpGet]
public IActionResult Get()
{
//return new JsonResult(from c in User.Claims select new { c.Type, c.Value });
return new OkObjectResult("OK");
}
}
class Program
{
static HttpClient _tokenClient = new HttpClient();
static DiscoveryCache _cache = new DiscoveryCache("http://localhost:5000");
static async Task Main()
{
Console.Title = "Console ResourceOwner Flow UserInfo";
var response = await RequestTokenAsync();
response.Show();
await CallServiceAsync(response.AccessToken);
}
static async Task CallServiceAsync(string token)
{
var baseAddress = "http://localhost:5000";
var client = new HttpClient
{
BaseAddress = new Uri(baseAddress)
};
client.SetBearerToken(token);
var response = await client.GetStringAsync("api/identity");
}
static async Task<TokenResponse> RequestTokenAsync()
{
var disco = await _cache.GetAsync();
if (disco.IsError) throw new Exception(disco.Error);
var response = await _tokenClient.RequestPasswordTokenAsync(new PasswordTokenRequest
{
Address = disco.TokenEndpoint,
ClientId = "client",
ClientSecret = "secret",
UserName = "bob",
Password = "bob",
Scope = "api1"
});
if (response.IsError) throw new Exception(response.Error);
return response;
}
}
示例客户端控制台应用程序:
namespace IdentityServer
{
public static class Config
{
public static IEnumerable<IdentityResource> GetIdentityResources()
{
return new IdentityResource[]
{
new IdentityResources.OpenId()
};
}
public static List<TestUser> GetUsers()
{
return new List<TestUser>
{
new TestUser
{
SubjectId = "1",
Username = "alice",
Password = "password"
},
new TestUser
{
SubjectId = "2",
Username = "bob",
Password = "bob"
}
};
}
public static IEnumerable<ApiResource> GetApis()
{
return new List<ApiResource>
{
new ApiResource("api1", "My API")
};
}
public static IEnumerable<Client> GetClients()
{
return new List<Client>
{
new Client
{
ClientId = "client",
RequireConsent = false,
AllowAccessTokensViaBrowser = true,
// no interactive user, use the clientid/secret for authentication
AllowedGrantTypes = GrantTypes.ResourceOwnerPasswordAndClientCredentials,
// secret for authentication
ClientSecrets =
{
new Secret("secret".Sha256())
},
// scopes that client has access to
AllowedScopes = { "api1" }
}
};
}
}
}
public class Startup
{
public IHostingEnvironment Environment { get; }
public Startup(IHostingEnvironment environment)
{
Environment = environment;
}
public void ConfigureServices(IServiceCollection services)
{
services
.AddMvcCore()
.AddJsonFormatters()
.AddAuthorization();
services.AddIdentityServer(options =>
{
options.Events.RaiseErrorEvents = true;
options.Events.RaiseInformationEvents = true;
options.Events.RaiseFailureEvents = true;
options.Events.RaiseSuccessEvents = true;
options.IssuerUri = "http://localhost:5000";
}
)
.AddInMemoryClients(Config.GetClients())
.AddInMemoryApiResources(Config.GetApis())
.AddInMemoryIdentityResources(Config.GetIdentityResources())
.AddDeveloperSigningCredential()
.AddJwtBearerClientAuthentication()
.AddTestUsers(Config.GetUsers());
services.AddAuthentication()
.AddIdentityServerAuthentication(o =>
{
o.Authority = "http://localhost:5000";
o.ApiName = "client";
o.ApiSecret = "secret";
o.EnableCaching = true;
o.RequireHttpsMetadata = false;
o.SaveToken = true;
}).AddCookie();
services.AddCors();
services.AddMvc();
}
public void Configure(IApplicationBuilder app)
{
app.UseCors(policy =>
{
policy.WithOrigins(
"http://localhost:5000",
"http://localhost:5001");
policy.AllowAnyHeader();
policy.AllowAnyMethod();
policy.WithExposedHeaders("WWW-Authenticate");
});
if (Environment.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseStaticFiles();
app.UseIdentityServer();
app.UseMvcWithDefaultRoute();
}
}
[Route("api/identity")]
[Authorize(AuthenticationSchemes = IdentityServerAuthenticationDefaults.AuthenticationScheme)]
public class IdentityController : ControllerBase
{
[HttpGet]
public IActionResult Get()
{
//return new JsonResult(from c in User.Claims select new { c.Type, c.Value });
return new OkObjectResult("OK");
}
}
class Program
{
static HttpClient _tokenClient = new HttpClient();
static DiscoveryCache _cache = new DiscoveryCache("http://localhost:5000");
static async Task Main()
{
Console.Title = "Console ResourceOwner Flow UserInfo";
var response = await RequestTokenAsync();
response.Show();
await CallServiceAsync(response.AccessToken);
}
static async Task CallServiceAsync(string token)
{
var baseAddress = "http://localhost:5000";
var client = new HttpClient
{
BaseAddress = new Uri(baseAddress)
};
client.SetBearerToken(token);
var response = await client.GetStringAsync("api/identity");
}
static async Task<TokenResponse> RequestTokenAsync()
{
var disco = await _cache.GetAsync();
if (disco.IsError) throw new Exception(disco.Error);
var response = await _tokenClient.RequestPasswordTokenAsync(new PasswordTokenRequest
{
Address = disco.TokenEndpoint,
ClientId = "client",
ClientSecret = "secret",
UserName = "bob",
Password = "bob",
Scope = "api1"
});
if (response.IsError) throw new Exception(response.Error);
return response;
}
}
类程序
{
静态HttpClient _tokenClient=新的HttpClient();
静态发现缓存_缓存=新发现缓存(“http://localhost:5000");
静态异步任务Main()
{
Console.Title=“Console ResourceOwner Flow UserInfo”;
var response=await RequestTokenAsync();
response.Show();
等待CallServiceAsync(response.AccessToken);
}
静态异步任务CallServiceAsync(字符串令牌)
{
var baseAddress=”http://localhost:5000";
var client=新的HttpClient
{
BaseAddress=新Uri(BaseAddress)
};
client.SetBearerToken(令牌);
var response=await client.GetStringAsync(“api/identity”);
}
静态异步任务RequestTokenAsync()
{
var disco=await_cache.GetAsync();
if(disco.IsError)抛出新异常(disco.Error);
var response=wait\u tokenClient.RequestPasswordTokenAsync(新的PasswordTokenRequest
{
地址=disco.tokenpoint,
ClientId=“客户端”,
ClientSecret=“secret”,
UserName=“bob”,
Password=“bob”,
Scope=“api1”
});
if(response.IsError)抛出新异常(response.Error);
返回响应;
}
}
在startup.cs.
中,您需要根据ApiResource
配置将ApiName
设置为api1
:
.AddIdentityServerAuthentication(o =>
{
...
o.ApiName = "api1";
...
}).AddCookie();