使用IdentityServer&;保护ASP.NET API;持票人

使用IdentityServer&;保护ASP.NET API;持票人,asp.net,identityserver4,bearer-token,Asp.net,Identityserver4,Bearer Token,我有一个三层应用程序,其中我有: blazor web应用程序 HTTP API 身份服务器 目前,我在HTTP API上有两种控制器: 通用API:无需身份验证即可访问,但仅当调用来自Web应用程序时 个人用途API:只有经过身份验证后才能访问 目前,“个人用途API”运行良好。此API仅在用户登录时可访问 但是,我还需要保护“通用API”不受任何黑客的攻击,现在对“post/list”的调用会返回一个“未经授权的错误” 我希望在不进行身份验证的情况下保护此API,但它必须只能从我的w

我有一个三层应用程序,其中我有:

  • blazor web应用程序
  • HTTP API
  • 身份服务器
目前,我在HTTP API上有两种控制器:

  • 通用API:无需身份验证即可访问,但仅当调用来自Web应用程序时
  • 个人用途API:只有经过身份验证后才能访问
目前,“个人用途API”运行良好。此API仅在用户登录时可访问

但是,我还需要保护“通用API”不受任何黑客的攻击,现在对“post/list”的调用会返回一个“未经授权的错误”

我希望在不进行身份验证的情况下保护此API,但它必须只能从我的web应用程序访问

你知道我怎么做吗?我的代码中是否有错误或缺失

以下是HTTP API端的控制器代码:

[Authorize]
[ApiController]
[Route("api/[controller]")]
public class PostsController : ControllerBase
{
        [HttpGet]
        [Route("post/list")]
        public async Task<List<Item>> GetListAsync()
        {
            ...
        }
}
context.Services.AddAuthentication(Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerDefaults.AuthenticationScheme)
.AddIdentityServerAuthentication(options =>
{
  options.Authority = configuration["AuthServer:Authority"];
  options.RequireHttpsMetadata = true;
  options.ApiName = "SoCloze";
});
以下是我在Web应用程序端的代码:

context.Services.AddAuthentication(options =>
        {
            options.DefaultScheme = "Cookies";
            options.DefaultChallengeScheme = "oidc";
        })
        .AddCookie("Cookies", options =>
        {
            options.ExpireTimeSpan = TimeSpan.FromDays(ApplicationConstants.LoginCookieExpirationDelay);
        })
        .AddOpenIdConnect("oidc", options =>
        {
            options.Authority = configuration["AuthServer:Authority"];
            options.RequireHttpsMetadata = true;
            options.ResponseType = OpenIdConnectResponseType.CodeIdToken;

            options.ClientId = configuration["AuthServer:ClientId"];
            options.ClientSecret = configuration["AuthServer:ClientSecret"];

            options.SaveTokens = true;
            options.GetClaimsFromUserInfoEndpoint = true;

            options.Scope.Add("role");
            options.Scope.Add("email");
            options.Scope.Add("phone");
            options.Scope.Add("SoCloze");

            options.ClaimActions.MapAbpClaimTypes();
        });

为了使API保持简单,您当然只希望接受来自trusted IdentityServer的令牌

因此,基本上您需要一个安全的通用访问令牌,但不与任何人类用户绑定。您可以让web应用使用客户端凭据流请求访问令牌,然后在您希望以未经身份验证的用户身份访问API时始终使用该令牌

在IdentityServer中,您可以为此设置单独的客户端

此外,使用IdentityModel库也可以帮助您(作为应用程序的工作人员)

另见

这张图片显示了我的意思:


为了保持API的简单,您当然只希望接受来自trusted IdentityServer的令牌

因此,基本上您需要一个安全的通用访问令牌,但不与任何人类用户绑定。您可以让web应用使用客户端凭据流请求访问令牌,然后在您希望以未经身份验证的用户身份访问API时始终使用该令牌

在IdentityServer中,您可以为此设置单独的客户端

此外,使用IdentityModel库也可以帮助您(作为应用程序的工作人员)

另见

这张图片显示了我的意思:


您应该使控制器匿名。通过配置,只需从控制器中删除Authorize属性。如果应用了全局策略,则需要将匿名属性添加到控制器:

[AllowAnonymous]
我不确定您想要实现什么,但我想您需要跨站点保护。也就是说,您希望限制某些端点仅从blazor应用程序的源访问

您需要信任的客户端浏览器。同一来源策略控制两个不同来源之间的交互

此保护仅适用于来自浏览器的XHR调用,不保护AGAINT的直接访问(邮递员、fiddler、任何http客户端…)

为了防止在帖子中出现跨源写入,您可以使用反伪造令牌。如果在表单中指定POST,则自动创建此令牌:

<form asp-controller="Todo" asp-action="Create" method="post">
    ...
</form>

这将拒绝以前未从服务器加载的任何表单中的任何帖子。

您应该使控制器匿名。通过配置,只需从控制器中删除Authorize属性。如果应用了全局策略,则需要将匿名属性添加到控制器:

[AllowAnonymous]
我不确定您想要实现什么,但我想您需要跨站点保护。也就是说,您希望限制某些端点仅从blazor应用程序的源访问

您需要信任的客户端浏览器。同一来源策略控制两个不同来源之间的交互

此保护仅适用于来自浏览器的XHR调用,不保护AGAINT的直接访问(邮递员、fiddler、任何http客户端…)

为了防止在帖子中出现跨源写入,您可以使用反伪造令牌。如果在表单中指定POST,则自动创建此令牌:

<form asp-controller="Todo" asp-action="Create" method="post">
    ...
</form>

这将拒绝以前未从服务器加载的任何表单中的任何帖子。

谢谢,但我会尽量避免直接访问,如邮递员等。。。如果我使用anonymous,我可以在没有令牌的情况下与邮递员通话,而且效果很好!看到了吗?那你一定需要某种身份验证。或者,您所说的“无需身份验证即可访问,但仅当调用来自Web应用程序时”是什么意思?我知道您需要从客户端应用程序(即浏览器)访问API,不是吗?例如,如果我有一个电子商务,提供产品列表的API只能由我的web应用程序访问,而不能由邮递员或其他人访问。但是,只有经过身份验证的用户才可以访问API to order。现在我有第二个,但我也希望有第一个,明白吗?我不希望任何应用程序,黑客等。。。在没有任何令牌的情况下调用我的“产品API列表”。根据您在第一种情况下所说的,信息实际上是公开的,也就是说,我可以访问它,而无需从浏览器进行任何身份验证。如果有人能以这样或那样的方式提取这些信息,即使是从邮递员那里,我也看不出有什么问题。在某个时刻,你必须向世界开放你的api以供消费。另一方面,如果你认为信息不是公开的,那么你必须对用户进行认证。谢谢,但是我试图保护直接访问,比如邮递员等等。如果我使用anonymous,我可以在没有令牌的情况下与邮递员通话,而且效果很好!看到了吗?那你一定需要某种身份验证。或者,您所说的“无需身份验证即可访问,但仅当调用来自Web应用程序时”是什么意思?我知道您需要从客户端应用程序(即浏览器)访问API,不是吗?举个例子,如果我有一个电子商务,则提供产品列表的API仅限于