我正在尝试在ASP.NET MVC Core应用程序(.NetCore 2)上使用IdentityServer4实现身份验证和访问控制。虽然这不是我第一次实现后端,但这是第一次使用.net,而且我正在努力解决一些问题。
我已按照https://identityserver4.readthedocs.io/en/release/quickstarts/1_client_credentials.html上的说明以及之前的页面进行操作。
我还在示例中添加了示例IdentityController
:
using System.Linq;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace leafserver.Controllers
{
[Route("/api/identity")]
[Authorize]
public class IdentityController : Controller
{
[HttpGet]
public IActionResult Get()
{
return new JsonResult(from c in User.Claims select new { c.Type, c.Value });
}
}
}
我的实现与他们的示例之间存在一些差异。据我所见:
ControllerBase
代替Controller
作为超类我注意到的是:
[Authorize]
,一切都很好。我得到200 OK的预期结果[Authorize]
注释存在,但我没有使用认证承载令牌时,我被重定向到登录页面(由于这是一个web api,这不起作用,但这是以后的问题)< / LI>
[Authorize]
注释存在时,我使用(我认为是)正确的身份验证令牌,我得到了404响应。我原本期待收到401响应。 为什么我的路由不能正常工作,因为我正在使用身份验证令牌?
另外,我没有从服务器获取任何日志,这没有帮助......
答案 0 :(得分:1)
好吧,我发现了问题。
在我的Startup.ConfigureServices
中,我修改了添加服务的顺序。
// https://identityserver4.readthedocs.io/en/release/quickstarts/1_client_credentials.html
services.AddIdentityServer()
.AddDeveloperSigningCredential()
.AddInMemoryApiResources(Config.GetApiResources())
.AddInMemoryClients(Config.GetClients())
.AddTestUsers(Config.GetTestUsers()); // TODO Remove for PROD
// This MUST stay below the AddIdentityServer, otherwise [Authorize] will cause 404s
services.AddAuthentication("Bearer")
.AddIdentityServerAuthentication(o =>
{
o.Authority = "http://localhost:5000";
o.RequireHttpsMetadata = false; // TODO Remove for PROD
o.ApiName = "leaf_api";
});
如果您在身份服务器之前添加身份验证,那么您将获得404。按此顺序,它可以正常工作。
以下是完整的Startup.cs
文件供参考:
using leafserver.Data;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Versioning;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
namespace leaf_server
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<LeafContext>(options => options.UseSqlite(Configuration.GetConnectionString("DefaultConnection")));
services.AddMvcCore()
.AddAuthorization()
.AddJsonFormatters();
// https://identityserver4.readthedocs.io/en/release/quickstarts/1_client_credentials.html
services.AddIdentityServer()
.AddDeveloperSigningCredential()
.AddInMemoryApiResources(Config.GetApiResources())
.AddInMemoryClients(Config.GetClients())
.AddTestUsers(Config.GetTestUsers()); // TODO Remove for PROD
// This MUST stay below the AddIdentityServer, otherwise [Authorize] will cause 404s
services.AddAuthentication("Bearer")
.AddIdentityServerAuthentication(o =>
{
o.Authority = "http://localhost:5000";
o.RequireHttpsMetadata = false; // TODO Remove for PROD
o.ApiName = "leaf_api";
});
// https://dotnetcoretutorials.com/2017/01/17/api-versioning-asp-net-core/
services.AddApiVersioning(o =>
{
o.ReportApiVersions = true;
o.AssumeDefaultVersionWhenUnspecified = true;
o.DefaultApiVersion = new ApiVersion(1, 0);
o.ApiVersionReader = new HeaderApiVersionReader("x-api-version");
});
}
// 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();
app.UseDatabaseErrorPage();
app.UseStatusCodePages();
}
app.UseIdentityServer();
app.UseAuthentication();
app.UseMvc();
}
}
}
答案 1 :(得分:1)
对我来说,答案是在我的控制器上设置Authorize属性,如此
[Authorize(AuthenticationSchemes = IdentityServerAuthenticationDefaults.AuthenticationScheme)]
,这是在leastprivilege指出的文档中概述的。 https://identityserver4.readthedocs.io/en/release/topics/add_apis.html
如果我只是[授权]那么它会产生404的