首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用ASP.NET & Bearer保护IdentityServer API

用ASP.NET & Bearer保护IdentityServer API
EN

Stack Overflow用户
提问于 2021-05-02 17:05:09
回答 2查看 192关注 0票数 0

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

  • blazor web应用程序
  • HTTP
  • 身份服务器

目前,我在HTTP上有两种控制器:

  • 通用API:可以在没有身份验证的情况下访问,但只有在调用来自Web应用程序的情况下才能访问。
  • 个人用途API:只能在认证后才能访问。

现在,“个人目的API”运行良好。只有当用户登录时,才能访问此API。

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

我想保护这个API,没有身份验证,但它必须只能从我的web应用程序访问。

你知道我该怎么做吗?我的代码有什么问题或遗漏了吗?

下面是HTTP端的控制器代码:

代码语言:javascript
复制
[Authorize]
[ApiController]
[Route("api/[controller]")]
public class PostsController : ControllerBase
{
        [HttpGet]
        [Route("post/list")]
        public async Task<List<Item>> GetListAsync()
        {
            ...
        }
}

下面是我在HTTP端的代码:

代码语言:javascript
复制
context.Services.AddAuthentication(Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerDefaults.AuthenticationScheme)
.AddIdentityServerAuthentication(options =>
{
  options.Authority = configuration["AuthServer:Authority"];
  options.RequireHttpsMetadata = true;
  options.ApiName = "SoCloze";
});

下面是我在Web应用程序端的代码:

代码语言:javascript
复制
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();
        });
EN

回答 2

Stack Overflow用户

发布于 2021-05-03 07:25:49

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

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

在IdentityServer中,您将为此设置一个单独的客户机。

此外,使用IdentityModel库可以帮助您在这里(作为一个工作应用程序)使用https://identitymodel.readthedocs.io/en/latest/aspnetcore/worker.html

另见https://docs.duendesoftware.com/identityserver/v5/tokens/requesting/

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

票数 1
EN

Stack Overflow用户

发布于 2021-05-03 11:43:01

你应该让你的控制器匿名。使用您的配置,只需从控制器中移除授权属性即可。如果应用了全局策略,则需要将匿名属性添加到控制器中:

代码语言:javascript
复制
[AllowAnonymous]

我不知道你想实现什么,但我想你想要跨站点保护。也就是说,您希望限制某些端点仅从您的blazor应用程序的原点访问。

您需要信任同一原产地政策的客户端浏览器。相同的原产地策略控制两个不同来源之间的交互。通常允许跨原点写入,通常允许跨原点嵌入,而跨原点读取通常不允许,但是通过嵌入,读取访问常常被泄露。

这种保护只适用于您的浏览器中的XHR调用,并且它不能防止直接访问(邮递员、吹手、任何http客户端.)。

若要防止文章中的跨源写入,可以使用防伪令牌。如果在表单中指定POST,Asp网络核心将自动创建此令牌:

代码语言:javascript
复制
<form asp-controller="Todo" asp-action="Create" method="post">
    ...
</form>

代码语言:javascript
复制
@using (Html.BeginForm("Create", "Todo"))
{
    ...
}

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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67359051

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档