gpt4 book ai didi

asp.net - 两个不同的 OWIN 应用程序能否授权一个 OAuth2 不记名访问 token ?

转载 作者:行者123 更新时间:2023-12-04 22:19:46 25 4
gpt4 key购买 nike

这个问题在这里已经有了答案:





Using Oauth tickets across several services?

(4 个回答)


5年前关闭。




我有两个 Web API:

  • 身份 API .它实现了认证、用户注册和OAuth客户端注册和认证。
  • 产品API .一组用于我的业务的 RESTful API。

  • 我使用 身份 API 验证资源所有者(即具有用户+密码凭据的用户)以使用 OAuth2 OWIN 中间件获取不记名 token 。

    我的问题是一旦我从 获得访问 token 身份 API ,我想用它来授权对 的请求产品API .

    两个 API 都在访问同一个数据库,而且现在都在同一台机器上。

    当我尝试针对 执行请求时产品API 我收到回复消息 "Authorization has been denied for this request" , 同时执行对 的请求身份 API 完美无缺。

    关键是我已经推导出 OAuthAuthorizationServerProvider满足一些自定义身份验证/授权要求,但在向 发出请求时,它永远不会到达这一点(永远不会调用 ValidateClientAuthenticationGrantResourceOwnerCredentials 方法)。产品API .

    我已经放弃了 OWIN 中间件的顺序可能会影响身份验证流程:两个 API 的配置方式完全相同。

    前几天...

    ...在尝试以这种方式工作之前,我正在考虑创建一个自定义 OAuthAuthorizationServerProvider和 ASP.NET Identity 用户存储来实际查询 身份 API 因此,在内部,身份验证和授权都将在颁发访问 token 的 OWIN 应用程序中进行验证。

    我已经为 ASP.NET Identity ( GitHub repository ) 实现了一个自定义用户存储,但我还没有实现一个 OAuthAuthorizationServerProvider发出 HTTP 请求,而不是直接使用底层数据库。

    Anwyay,我想知道我是否可以暂时避免走这条路, 如果我可以从 OWIN 应用程序发出访问 token 并使用来自具有不同主机和端口的不同 OWIN 应用程序的访问 token 。

    更新:调试 System.Web.Http

    我下载了 System.Web.Http源代码来自 ASP.NET Web Stack GitHub repository我也编译了它,并将编译后的程序集链接到我的 产品API WebAPI 项目调试 AuthorizeAttribute .

    收到整个不记名 token 但 actionContext.ControllerContext.RequestContext.Principalnull .我怀疑某些与 OAuth 相关的中间件没有解密并将用户分配给整个属性。

    关键是同样的道理也适用于 身份 API .

    检查以下屏幕截图,我可以在其中证明正在接收不记名 token :

    enter image description here

    更新 2:身份 API 可以使用发出的访问 token 授权请求...

    我可以确认访问 token 可以授权对 Identity API 资源的请求(例如,我已经实现了 UserController 来让 Identity API 注册和管理用户,并且大多数 Controller 操作都标有 [Authorize] 属性...)。

    最佳答案

    是的,您可以将授权服务器和资源服务器解耦。
    他们可以生活在不同的 owin 应用程序中,不仅如此,他们甚至可以生活在不同的服务器上。

    授权服务器将负责向您的客户端应用程序颁发访问 token ,并最终管理用户和角色。

    资源服务器将托管 protected 资源,接受授权服务器发布的访问 token 。

    查看您的基础设施 身份 API 将是授权服务器和 产品API 将是您的资源服务器。

    授权服务器需要配置和使用 OAuthAuthorizationServerProvider 的实现.
    在你的初创公司中,你会做这样的事情:

    app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);

    var OAuthOptions = new OAuthAuthorizationServerOptions
    {
    AllowInsecureHttp = true,
    TokenEndpointPath = new PathString("/oauth/Token"),
    AccessTokenExpireTimeSpan = TimeSpan.FromHours(8),
    Provider = new MyAuthorizationServerProvider(),
    // RefreshTokenProvider = new MyRefreshTokenProvider(DateTime.UtcNow.AddHours(8))
    };

    app.UseOAuthAuthorizationServer(OAuthOptions);
    app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());

    如您所见,我使用了 MyAuthorizationServerProvider作为身份验证的自定义提供程序。

    它负责验证客户端( ValidateClientAuthentication )并授予访问资源的权限( GrantResourceOwnerCredentials )。
    GrantResourceOwnerCredentials将检查客户端的凭据(用户名和密码)是否有效并释放有效 token :
    var ticket = new AuthenticationTicket(identity, props);
    context.Validated(ticket);
    AuthenticationTicket收到 ClaimsIdentity对象和 AuthenticationProperties 的集合.

    您通常会在此处添加用户名声明和角色:
    ClaimsIdentity identity = new ClaimsIdentity(context.Options.AuthenticationType);
    identity.AddClaim(new Claim(ClaimTypes.Name, context.UserName));
    identity.AddClaim(new Claim(ClaimTypes.Role, "Users"));

    以及最终您可能想要使用的其他类型的声明。 AuthenticationProperties集合将定义您要传递给客户端的扩展信息:
    var props = new AuthenticationProperties(new Dictionary<string, string>
    {
    {
    "name", "John"
    },
    {
    "surname", "Smith"
    },
    {
    "age", "40"
    },
    {
    "gender", "Male"
    }
    });

    你可以查看这个github repo看看实现。

    您的资源服务器,即负责管理您的业务信息的 RESTful API,将不必重新实现整个授权/身份验证层。

    在您的启动( Product API )中,您只需指示 api 使用和消费不记名 token :
    public void Configuration(IAppBuilder app)
    {
    HttpConfiguration config = new HttpConfiguration();

    OAuthBearerAuthenticationOptions OAuthBearerOptions = new OAuthBearerAuthenticationOptions();
    app.UseOAuthBearerAuthentication(OAuthBearerOptions);

    WebApiConfig.Register(config);
    app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
    app.UseWebApi(config);
    }

    您的 protected 资源将是这样的:
    [Authorize(Roles = "Users")]
    public class ProductsController : ApiController
    {
    public Models.Product GetProduct(string id)
    {
    var identity = User.Identity as ClaimsIdentity;

    return new Models.Product();
    }
    }

    如您所见,我使用了 Authorize属性原因我只想授权某种类型的用户。

    注意:

    如果您想托管 授权服务器资源服务器在不同的机器上,您必须确保共享相同的 machineKey无论是服务器还是资源服务器都无法解密 释放的承载 token 。授权服务器 :
    <system.web>
    <compilation debug="true" targetFramework="4.5" />
    <httpRuntime targetFramework="4.5" />
    <machineKey validationKey="VALUE GOES HERE"
    decryptionKey="VALUE GOES HERE"
    validation="SHA1"
    decryption="AES"/>
    </system.web>

    我建议你阅读这个 article找到关于所有涉及的部分的非常好的解释。

    Taisser 也作为另一个 article他使用 Json Web Tokens 经历了相同的过程来实现相同的结果。

    关于asp.net - 两个不同的 OWIN 应用程序能否授权一个 OAuth2 不记名访问 token ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34021254/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com