Identity Server 4上授权客户端的自定义终结点 [英] Custom endpoint for authorized clients on Identity Server 4

查看:148
本文介绍了Identity Server 4上授权客户端的自定义终结点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望我的Identity Server 4服务器为某些已注册的客户端提供附加服务(例如,"MyAdditionalService").他们将通过要在服务器上定义的自定义端点来使用该服务.

我正在考虑为该服务定义一个API(例如,名为"myAdditionalService"),以便可以根据客户端的配置将对此类服务的访问权限授予客户端.但是我不确定如何限制对端点的访问(MVC-Action方法),该端点仅允许被允许使用API​​的客户端(可能代表用户).

我发现我可以做到:

services.AddAuthorization(options =>
     {
       options.AddPolicy("MyAdditionalServicePolicy",
           policy => policy.RequireClaim("scope", 
           "myAdditionalService"));
      });

,并使用属性[Authorize("MyAdditionalServicePolicy")]装饰用于访问此类服务的操作方法.但是,我不知道服务器是否可以同时成为API,或者即使可能也可以.

我该如何实施?令牌服务还扮演着API的角色,这令人困惑,因为它可以保护对操作方法或端点的访问.

谢谢.


更新:

我的Web应用程序是一个IdentityServerWithAspNetIdentity,它已经使用Asp.net核心身份的身份验证机制.为了举例说明,我的Web应用程序向某些注册客户提供的附加服务是用户的Twitter朋友列表(在名为Twitter的控制器上建模,名为ImportFriends的操作),因此api被称为"TwitterFriends"

根据下面的响应建议,我将Configure()方法修改为具有app.UseJwtBearerAuthentication().我已经有app.UseIdentity()app.UseIdentityServer(),如下所示:

        app.UseIdentity();
        app.UseIdentityServer();


        app.UseJwtBearerAuthentication(new JwtBearerOptions
        {
            AuthenticationScheme = "Bearer",
            Authority = Configuration["BaseUrl"],
            Audience = "TwitterFriends",
            RequireHttpsMetadata = false                 //TODO: make true, it is false for development only
        });

        // Add external authentication middleware below. To configure them please see http://go.microsoft.com/fwlink/?LinkID=532715
        app.UseGoogleAuthentication(new GoogleOptions
        {
            AuthenticationScheme = "Google",
            SignInScheme = "Identity.External", // this is the name of the cookie middleware registered by UseIdentity()

在专用控制器上:

 [Authorize(ActiveAuthenticationSchemes = "Identity.Application,Bearer")]
//[Authorize(ActiveAuthenticationSchemes = "Identity.Application")]
//[Authorize(ActiveAuthenticationSchemes = "Bearer")]
[SecurityHeaders]
public class TwitterController : Controller
{...

但是我在日志中得到了这个

info: Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationMiddleware
[7]
      Identity.Application was not authenticated. Failure message: Unprotect tic
ket failed
info: Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[2]
      Authorization failed for user: (null).
info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[1]
      Authorization failed for the request at filter 'Microsoft.AspNetCore.Mvc.A
uthorization.AuthorizeFilter'.
info: Microsoft.AspNetCore.Mvc.ChallengeResult[1]
      Executing ChallengeResult with authentication schemes (Identity.Applicatio
n, Bearer).
info: Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationMiddleware
[12]
      AuthenticationScheme: Identity.Application was challenged.
info: Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerMiddleware[12]
      AuthenticationScheme: Bearer was challenged.
info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[2]
      Executed action IdentityServerWithAspNetIdentity.Controllers.TwitterContro
ller.ImportFriends (IdentityServerWithAspNetIdentity) in 86.255ms
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
      Request finished in 105.2844ms 401

我尝试了该属性的不同组合,但在这种情况下,Identity.Application和Bearer似乎相处并不融洽:获得401.

任何帮助,我们感激不尽. 谢谢.

解决方案

请参见此示例,以了解如何在与IdentityServer相同的Web应用程序中托管API.

https://github.com/brockallen/IdentityServerAndApi

本质上,您需要添加JWT令牌验证处理程序:

services.AddAuthentication() .AddJwtBearer(jwt => { jwt.Authority = "base_address_of_identityserver"; jwt.Audience = "name of api"; });

在API本身上,您必须选择JWT身份验证方案:

public class TestController : ControllerBase { [Route("test")] [Authorize(AuthenticationSchemes = "Bearer")] public IActionResult Get() { var claims = User.Claims.Select(c => new { c.Type, c.Value }).ToArray(); return Ok(new { message = "Hello API", claims }); } }

如果要实施其他授权策略,可以将其传递到[Authorize]属性中,也可以强制性地调用它.

I want my Identity Server 4 server to offer an additional service (e.g., "MyAdditionalService") for SOME of the registered clients. That service will be consumed by them through a custom endpoint to be defined on the server.

I am thinking of defining an API for my that service (e.g., named "myAdditionalService") so that the access to such service can be granted to clients according to their configuration. However I am not sure how to restrict the access to the Endpoint (MVC - Action method) allowing only the clients (potentially on behalf of a user) that are allowed to consume the API.

I found out that I can do:

services.AddAuthorization(options =>
     {
       options.AddPolicy("MyAdditionalServicePolicy",
           policy => policy.RequireClaim("scope", 
           "myAdditionalService"));
      });

and use the attribute [Authorize("MyAdditionalServicePolicy")] to decorate the action method that is used to access such service. However, I don't know can the server be the API at the same time or even if it is possible.

How can I implement this? It is confusing that the token service plays the role of the API as well, since it protects access to an action method or endpoint.

Thanks.


UPDATE:

My web app is an IdentityServerWithAspNetIdentity which already use the Authentication mechanism of Asp.net core Identity. For the sake of the example, the additional service my web app if offering to some registered clients is the list of Twitter friends of a user (Modeled on a controller called Twitter, action called ImportFriends) the api is consequently called "TwitterFriends"

As per suggestion in response below, I modified my Configure() method to have app.UseJwtBearerAuthentication(). I already had app.UseIdentity() and app.UseIdentityServer() as shown below:

        app.UseIdentity();
        app.UseIdentityServer();


        app.UseJwtBearerAuthentication(new JwtBearerOptions
        {
            AuthenticationScheme = "Bearer",
            Authority = Configuration["BaseUrl"],
            Audience = "TwitterFriends",
            RequireHttpsMetadata = false                 //TODO: make true, it is false for development only
        });

        // Add external authentication middleware below. To configure them please see http://go.microsoft.com/fwlink/?LinkID=532715
        app.UseGoogleAuthentication(new GoogleOptions
        {
            AuthenticationScheme = "Google",
            SignInScheme = "Identity.External", // this is the name of the cookie middleware registered by UseIdentity()

And on a dedicated controller:

 [Authorize(ActiveAuthenticationSchemes = "Identity.Application,Bearer")]
//[Authorize(ActiveAuthenticationSchemes = "Identity.Application")]
//[Authorize(ActiveAuthenticationSchemes = "Bearer")]
[SecurityHeaders]
public class TwitterController : Controller
{...

but I am getting this in the log:

info: Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationMiddleware
[7]
      Identity.Application was not authenticated. Failure message: Unprotect tic
ket failed
info: Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[2]
      Authorization failed for user: (null).
info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[1]
      Authorization failed for the request at filter 'Microsoft.AspNetCore.Mvc.A
uthorization.AuthorizeFilter'.
info: Microsoft.AspNetCore.Mvc.ChallengeResult[1]
      Executing ChallengeResult with authentication schemes (Identity.Applicatio
n, Bearer).
info: Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationMiddleware
[12]
      AuthenticationScheme: Identity.Application was challenged.
info: Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerMiddleware[12]
      AuthenticationScheme: Bearer was challenged.
info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[2]
      Executed action IdentityServerWithAspNetIdentity.Controllers.TwitterContro
ller.ImportFriends (IdentityServerWithAspNetIdentity) in 86.255ms
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
      Request finished in 105.2844ms 401

I have tried different combinations of the attribute but it seems that Identity.Application and Bearer don't get along in this scenario: getting 401.

any help is appreciated. Thanks..

解决方案

See this example on how to host an API in the same web app as IdentityServer.

https://github.com/brockallen/IdentityServerAndApi

In essence you need to add the JWT token validation handler:

services.AddAuthentication() .AddJwtBearer(jwt => { jwt.Authority = "base_address_of_identityserver"; jwt.Audience = "name of api"; });

On the API itself you must select the JWT authentication scheme:

public class TestController : ControllerBase { [Route("test")] [Authorize(AuthenticationSchemes = "Bearer")] public IActionResult Get() { var claims = User.Claims.Select(c => new { c.Type, c.Value }).ToArray(); return Ok(new { message = "Hello API", claims }); } }

If you want to enforce an additional authorization policy, you can either pass that into the [Authorize] attribute or call it imperatively.

这篇关于Identity Server 4上授权客户端的自定义终结点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆