gpt4 book ai didi

c# - 为使用 IdentityServer4 进行身份验证的 Asp Net Core API 构建集成测试

转载 作者:行者123 更新时间:2023-12-02 03:17:51 24 4
gpt4 key购买 nike

我构建了一个简单的 AspNetCore 2.2 API,它使用 IdentityServer 4 来处理 OAuth。它工作正常,但我现在想添加集成测试,最近发现 this 。我用它构建了一些测试,这些测试都运行良好 - 只要我的 Controller 上没有 [Authorize] 属性 - 但显然该属性需要存在。

我遇到了this stackoverflow question根据那里给出的答案,我尝试将测试放在一起,但当我尝试运行测试时,我仍然收到 Unauthorized 响应。

请注意:我真的不知道在创建客户端时应该使用哪些详细信息。

  • 允许的范围应该是什么? (它们应该与真实的相符吗?范围)

构建 IdentityServerWebHostBuilder 时也是如此

  • 我应该将什么传递给 .AddApiResources? (也许是个愚蠢的问题,但是这有关系吗)

如果有人能指导我,我将不胜感激。

这是我的测试:

[Fact]
public async Task Attempt_To_Test_InMemory_IdentityServer()
{
// Create a client
var clientConfiguration = new ClientConfiguration("MyClient", "MySecret");

var client = new Client
{
ClientId = clientConfiguration.Id,
ClientSecrets = new List<Secret>
{
new Secret(clientConfiguration.Secret.Sha256())
},
AllowedScopes = new[] { "api1" },
AllowedGrantTypes = new[] { GrantType.ClientCredentials },
AccessTokenType = AccessTokenType.Jwt,
AllowOfflineAccess = true
};

var webHostBuilder = new IdentityServerWebHostBuilder()
.AddClients(client)
.AddApiResources(new ApiResource("api1", "api1name"))
.CreateWebHostBuilder();

var identityServerProxy = new IdentityServerProxy(webHostBuilder);
var tokenResponse = await identityServerProxy.GetClientAccessTokenAsync(clientConfiguration, "api1");

// *****
// Note: creating an IdentityServerProxy above in order to get an access token
// causes the next line to throw an exception stating: WebHostBuilder allows creation only of a single instance of WebHost
// *****

// Create an auth server from the IdentityServerWebHostBuilder
HttpMessageHandler handler;
try
{
var fakeAuthServer = new TestServer(webHostBuilder);
handler = fakeAuthServer.CreateHandler();
}
catch (Exception e)
{
throw;
}

// Create an auth server from the IdentityServerWebHostBuilder
HttpMessageHandler handler;
try
{
var fakeAuthServer = new TestServer(webHostBuilder);
handler = fakeAuthServer.CreateHandler();
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}

// Set the BackChannelHandler of the 'production' IdentityServer to use the
// handler form the fakeAuthServer
Startup.BackChannelHandler = handler;
// Create the apiServer
var apiServer = new TestServer(new WebHostBuilder().UseStartup<Startup>());
var apiClient = apiServer.CreateClient();


apiClient.SetBearerToken(tokenResponse.AccessToken);

var user = new User
{
Username = "<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="6b18020604050704060a132b0e000645080406" rel="noreferrer noopener nofollow">[email protected]</a>",
Password = "Password-123"
};

var req = new HttpRequestMessage(new HttpMethod("GET"), "/api/users/login")
{
Content = new StringContent(JsonConvert.SerializeObject(user), Encoding.UTF8, "application/json"),
};

// Act
var response = await apiClient.SendAsync(req);

// Assert
Assert.Equal(HttpStatusCode.OK, response.StatusCode);

}

我的启动类(class):

public class Startup
{

public IConfiguration Configuration { get; }
public static HttpMessageHandler BackChannelHandler { get; set; }

public Startup(IConfiguration configuration)
{
Configuration = configuration;
}

// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
ConfigureAuth(services);
services.AddTransient<IPassportService, PassportService>();
services.Configure<ApiBehaviorOptions>(options =>
{
options.SuppressModelStateInvalidFilter = true;
});

}

protected virtual void ConfigureAuth(IServiceCollection services)
{
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.Authority = Configuration.GetValue<string>("IdentityServerAuthority");
options.Audience = Configuration.GetValue<string>("IdentityServerAudience");
options.BackchannelHttpHandler = BackChannelHandler;
});
}


// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseHsts();
}

app.UseAuthentication();
app.UseHttpsRedirection();
app.UseMvc();
app.UseExceptionMiddleware();
}
}

最佳答案

编辑:

下面的建议是一个问题。由于尝试构建 WebHostBuilder 时出现异常,原始源代码失败 twice 。其次,配置文件仅存在于 API 项目中,而不存在于测试项目中,这就是权限未设置的原因。

而不是这样做

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.Authority = Configuration.GetValue<string>("IdentityServerAuthority");
options.Audience = Configuration.GetValue<string>("IdentityServerAudience");
options.BackchannelHttpHandler = BackChannelHandler;
});

你必须做这样的事情:

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddIdentityServerAuthentication(options =>
{
options.Authority = Configuration.GetValue<string>("IdentityServerAuthority");
options.JwtBackChannelHandler = BackChannelHandler;
});

您可以找到示例here .

希望有帮助,对我有用!

关于c# - 为使用 IdentityServer4 进行身份验证的 Asp Net Core API 构建集成测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55590928/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com