使用Asp.Net Core WebAPI进行授权

时间:2017-02-15 18:36:08

标签: asp.net-web-api .net-core identityserver4

不可否认,这是建立Asp.Net Core web api项目的第一步。一个要求是支持OAuth2。 Api和Identity服务器是两个独立的项目,都是从Asp.Net核心空模板开始的。

身份服务器已启动并正在运行,并且正在通过资源所有者流提供令牌。获取令牌很好,范围和相关的access_token详细信息似乎是正确的。

当我向我的资源端点发出get请求时,我首先得到以下内容......

info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
      Request starting HTTP/1.1 GET http://localhost:12886/v1/mystuff
info: Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerMiddleware[2]
      Successfully validated the token.
info: Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerMiddleware[3]
      HttpContext.User merged via AutomaticAuthentication from authenticationScheme: Bearer.
info: Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerMiddleware[8]
      AuthenticationScheme: Bearer was successfully authenticated.
info: IdentityModel.AspNetCore.ScopeValidation.ScopeValidationMiddleware[0]
      Scopes found on current principal: scope: stuffdetails, scope: stuffmover
info: Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerMiddleware[8]
      AuthenticationScheme: Bearer was successfully authenticated.
info: Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[1]
      Authorization was successful for user: 939d72dd-654c-447f-a65d-d0426b1eca59.

所以,我可以告诉中间件正在验证我的令牌,读取范围以及验证令牌。 但是,在最初的成功之后,我立即获得授权失败。

info: Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[2]
      Authorization failed for user: 939d72dd-654c-447f-a65d-d0426b1eca59.
info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[1]
      Authorization failed for the request at filter 'Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter'.
info: Microsoft.AspNetCore.Mvc.ChallengeResult[1]
      Executing ChallengeResult with authentication schemes ().
info: Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerMiddleware[13]
      AuthenticationScheme: Bearer was forbidden.
info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[2]
      Executed action TestApi.StuffController.GetStuff (TestApi) in 32.4439ms
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
      Request finished in 1207.1769ms 403

以下是我认为启动时的相关内容。

ConfigureServices ...

services.AddMvcCore()
        .AddAuthorization(opts =>
            {
                opts.AddPolicy("stuffdetails",
                    policy => policy.RequireClaim("stuffdetails"));
            }
        )
        .AddJsonFormatters();

services.AddOptions();

配置 - 请注意,我知道我的configOptions是正确的,因为初始令牌挑战是成功的。

var authServerOptions = new IdentityServerAuthenticationOptions
{
    Authority =  configOptions.Value.AuthServerSettings.AuthServerURI,
    RequireHttpsMetadata = configOptions.Value.AuthServerSettings.RequiresHttpsMetaData,
    ApiName = configOptions.Value.AuthServerSettings.ApiName,
    AllowedScopes = configOptions.Value.AuthServerSettings.AllowedScopes,
    SupportedTokens = IdentityServer4.AccessTokenValidation.SupportedTokens.Jwt,
    AuthenticationScheme = "Bearer",
    SaveToken = true,
    ValidateScope = true
};

app.UseIdentityServerAuthentication(authServerOptions);
app.UseMvc();

填充控制器

[Route("v1/[controller]")]
[Authorize(ActiveAuthenticationSchemes = "Bearer")]
public class StuffController : Controller
{
    [HttpGet]
    [Authorize(Policy = "stuffdetails")]
    public JsonResult GetStuff()
    {
        return new JsonResult(new
        {
            Message = "You've got stuff.."
        });
    }
}

如果我从GetStuff方法中删除Authorize属性,一切都很好,因为正如日志所示,持有者令牌已获得授权。

问题:

  1. 授权失败是因为我的政策不正确,如果是,应该如何设置?
  2. 如果我想验证令牌包含正确的声明并获得授权,那么使用策略是否正确?
  3. 我是否在尝试使用 UseIdentityServerAuthentication 而不是 UseJwtBearerAuthentication 时犯了错误?
  4. 非常感谢任何帮助..

3 个答案:

答案 0 :(得分:2)

  

授权失败是因为我的政策不正确,如果是,那么如何   应该设置吗?

您所拥有的内容看起来是正确的,但只需删除“政策”即可轻松验证。 Authorize属性的一部分:如果它现在有效,则问题与您的策略有关,如果它仍然失败,那么这是一个比您的策略更广泛的问题。我假设你正在添加' stuffdetails'使用您自己的IProfileService

实现声明您的access_token
  

如果我想验证令牌包含正确的声明,那么   授权,使用我的政策是否正确?

是的,这似乎是aspnet进行自定义授权的核心方式。

  

尝试使用UseIdentityServerAuthentication时出错了   而不是UseJwtBearerAuthentication?

我正在使用带有UseIdentityServerAuthentication流量的ResourceOwnerPassword。我很想知道UseJwtBearerAuthentication方法是首选还是提供其他功能。

答案 1 :(得分:1)

我的错误是我创建政策的方式:

opts.AddPolicy("stuffdetails",
                            policy => policy.RequireClaim("stuffdetails"));

应该是:

opts.AddPolicy("stuffdetails",
                            policy => policy.RequireClaim("scope","stuffdetails"));

该政策应该确认范围包括“stuffdetails”..对于遇到麻烦的人来说,一个很好的资源是damienbod的帖子,Authorization Policies and Data Protection with IdentityServer4 in ASP.Net Cord

答案 2 :(得分:0)

此外,您可以利用Microsoft.Aspnetcore.Authorization来实现此功能。 主要优点是它更易于阅读,并且允许您指定多个范围(联合/或)。

opts.AddPolicy("stuffdetails", ScopePolicy.Create("stuffdetails", "stuffdetails2"));

代替

opts.AddPolicy("stuffdetails",
                        policy => policy.RequireClaim("scope","stuffdetails"));