[英]IdentityServer4 with Resource API in .NET 4.5 (OWIN)
我已经阅读了大量的示例以及IdentityServer 4文档,但我似乎仍然遗漏了一些东西。
基本上,我有IdentityServer4工作到它证明我是AccessToken
和RefreshToken
。 然后我尝试使用该AccessToken
并向我的WebAPI2(.NET 4.5,OWIN)发送HTTP请求,该请求使用IdentityServer3.AccessTokenValidation
,它应该基于https://github.com/IdentityServer/CrossVersionIntegrationTests/上的样本/测试进行兼容。
当我尝试访问需要授权的资源时,WebAPI2正在给我HTTP 400,而我真的一无所知它为什么会发生。
这是代码:
QuickstartIdentityServer Startup.cs
public void ConfigureServices(IServiceCollection services)
{
var connectionString = @"server=(localdb)\mssqllocaldb;database=IdentityServer4.Quickstart.EntityFramework;trusted_connection=yes";
var migrationsAssembly = typeof(Startup).GetTypeInfo().Assembly.GetName().Name;
// configure identity server with in-memory stores, keys, clients and scopes
var identityServerConfig = services.AddIdentityServer()
.AddConfigurationStore(builder =>
builder.UseSqlServer(connectionString, options =>
options.MigrationsAssembly(migrationsAssembly)))
.AddOperationalStore(builder =>
builder.UseSqlServer(connectionString, options =>
options.MigrationsAssembly(migrationsAssembly)))
.AddSigningCredential(new X509Certificate2(Path.Combine(_environment.ContentRootPath, "certs", "IdentityServer4Auth.pfx"), "test"));
identityServerConfig.Services.AddTransient<IResourceOwnerPasswordValidator, ActiveDirectoryPasswordValidator>();
identityServerConfig.Services.AddTransient<IProfileService, CustomProfileService>();
services.AddMvc();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
InitializeDatabase(app);
app.UseDeveloperExceptionPage();
app.UseIdentityServer();
app.UseMvcWithDefaultRoute();
}
QuickstartIdentityServer Config.cs(我以前为我的数据库播种)
public class Config
{
// scopes define the API resources in your system
public static IEnumerable<ApiResource> GetApiResources()
{
return new List<ApiResource>
{
new ApiResource("api1", "My API")
{
Scopes = new [] { new Scope("api1"), new Scope("offline_access") },
UserClaims = { ClaimTypes.Role, "user" }
}
};
}
// client want to access resources (aka scopes)
public static IEnumerable<Client> GetClients()
{
// client credentials client
return new List<Client>
{
new Client
{
ClientId = "client",
AllowedGrantTypes = GrantTypes.ClientCredentials,
ClientSecrets =
{
new Secret("secret".Sha256())
},
AllowedScopes = { "api1" }
},
// resource owner password grant client
new Client
{
ClientId = "ro.client",
AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,
ClientSecrets =
{
new Secret("secret".Sha256())
},
UpdateAccessTokenClaimsOnRefresh = true,
AllowedScopes = { "api1", "offline_access" },
AbsoluteRefreshTokenLifetime = 86400,
AllowOfflineAccess = true,
RefreshTokenUsage = TokenUsage.ReUse
}
};
}
}
WebAPI2 Startup.cs
public void Configuration(IAppBuilder app)
{
HttpConfiguration config = new HttpConfiguration();
config.MapHttpAttributeRoutes();
app.UseIdentityServerBearerTokenAuthentication(new IdentityServerBearerTokenAuthenticationOptions
{
Authority = "http://localhost:44340/",
RequiredScopes = new[] { "api1" },
DelayLoadMetadata = true
});
WebApiConfig.Register(config);
app.UseWebApi(config);
}
WebAPI2 TestController
public class TestController : ApiController
{
// GET: api/Test
[Authorize]
public async Task<IHttpActionResult> Get()
{
return Json(new { Value1 = "value1", Value2 = "value2" });
}
}
ConsoleApplication来测试这个:
private static async Task MainAsync()
{
// discover endpoints from metadata
//DiscoveryClient client = new DiscoveryClient("https://dev-ea-authapi");
DiscoveryClient client = new DiscoveryClient("http://localhost:44340/");
client.Policy.RequireHttps = false;
var disco = await client.GetAsync();
// request token
var tokenClient = new TokenClient(disco.TokenEndpoint, "ro.client", "secret");
var tokenResponse = await tokenClient.RequestResourceOwnerPasswordAsync("likosto", "CrM75fnza%");
if (tokenResponse.IsError)
{
Console.WriteLine(tokenResponse.Error);
return;
}
Console.WriteLine(tokenResponse.Json);
Console.WriteLine("\n\n");
//var newTokenResponse = await tokenClient.RequestRefreshTokenAsync(tokenResponse.RefreshToken);
// call api
var httpClient = new HttpClient();
httpClient.SetBearerToken(tokenResponse.AccessToken);
var response = await httpClient.GetAsync("http://localhost:21715/api/test");
if (!response.IsSuccessStatusCode)
{
Console.WriteLine(response.StatusCode);
// HTTP StatusCode = 400 HERE <======================
}
else
{
var content = response.Content.ReadAsStringAsync().Result;
Console.WriteLine(JArray.Parse(content));
}
}
在仔细研究之后,这是因为我在我的令牌中添加了一些非常大的数据集作为实验。 IIS正在发送HTTP 400,因为请求标头太长。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.