如何使 AuthorizeEndpointPath 在 ASP.NET Oauth 2.0 框架中工作 [英] How do I make the AuthorizeEndpointPath work in ASP.NET Oauth 2.0 framework

查看:62
本文介绍了如何使 AuthorizeEndpointPath 在 ASP.NET Oauth 2.0 框架中工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前有一个网站,我正在尝试实施 OAuth 服务器框架.该网站目前是 Web Forms(不是 MVC)和 Web API 2 的组合.就我想要做的而言,我们无法更改系统的整体架构.

I currently have a website where I am trying to implement the OAuth server framework. The website is currently a combination of Web Forms (not MVC) and Web API 2. For the purposes of what I am trying to do, we cannot change the overall architecture of the system.

到目前为止,我已经通过 Web API 使用 OAuth 来验证客户端、生成访问令牌和处理刷新令牌.

So far, I have OAuth working via the Web API for validating clients, generating access tokens, and handling refresh tokens.

我尝试实施的最后一部分是授权代码工作流程.这将允许我们授予对应用程序的访问权限,以便集成工具可以访问我们的 API,而无需在本地存储用户凭据.

The last piece I am trying to implement is the Authorize Code workflow. This will allow us to grant access to our application so integration tools can access our APIs without having to locally store the user credentials.

我对它应该如何运作的理解如下:

My understanding of how it should function is the following:

  1. 用户被定向到我在 Startup.Auth 文件中定义的 AuthorizeEndpointPath
  2. 用户要么看到一个登录页面(如果他们还没有网站的身份验证 cookie),要么他们看到一个特殊的页面,在那里他们必须授予访问帐户的权限(类似于 Google 拥有的页面)
  3. 立>
  4. 一旦用户点击授予"按钮,OWIN 中间件将处理请求,并将它们重定向回请求访问的原始客户端 URL

但是,在我所有的配置之后,每当我直接访问 AuthorizeEndpointPath 时,实际上从未显示授予访问权限"页面.

However, after all of my configuration, whenever I access the AuthorizeEndpointPath directly, the "grant access permission" page is never actually displayed.

我确保了以下配置,但没有太多关于正确配置的文档.

I've ensured the following configuration, but there isn't much documentation on what the correct configuration is.

var oAuthServerOptions = new OAuthAuthorizationServerOptions()
            {
                AllowInsecureHttp = true,
                TokenEndpointPath = new PathString("/api/token"),
                AuthorizeEndpointPath = new PathString("/LoginAuthorize.aspx"),
                //AuthorizeEndpointPath = new PathString("/api/authorize"),
                AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(10),
                Provider = new ApiAuthorizationServerProvider(),
                RefreshTokenProvider = new ApiRefreshTokenProvider(),
                AuthorizationCodeProvider = new ApiAuthoirzationCodeProvider()
            };

目前AuthorizeEndpointPath"属性映射到一个实际页面,我要求用户确认,但该页面根本没有显示

Currently the "AuthorizeEndpointPath" property maps to an actual page, where I ask the user confirmation, but that page is not being displayed at all

通过调试,我可以看到框架甚至在加载授权页面之前就命中了以下方法

Through debugging, I can see the framework hits the following method even before the authorization page would be loaded

ValidateClientRedirectUri(OAuthValidateClientRedirectUriContext context)

我试图重载该方法,但发生了两件事之一.如果我调用 context.Validated();,用户会被立即重定向而不显示授权页面.如果不验证"重定向 URI,则会显示一个空白页面,指示invalid_request".

I have tried to overload that method, and one of 2 things happens. If I make a call to context.Validated();, the user is immediately redirected without the authorization page being displayed. If don't "validate" the redirect URI, then a blank page is displayed indicating an "invalid_request".

所以最大的问题是如何让 OWIN 显示我的自定义授权页面?

当最终显示授权页面时,当用户点击grant"按钮时我需要做什么.是否有任何我需要设置的配置,或者我需要对 OWIN 进行任何调用?

When the authorization page is finally displayed, what would I need to do when the user clicks on the "grant" button. Is there any configuration I need to setup, or any calls to OWIN I need to make?

此外,我如何确保用户在显示该页面之前进行身份验证?如果用户未登录,我是否只需让我的代码将用户重定向到登录页面?如果是这样,OWIN 将如何处理真正的重定向回客户端(如果用户登录后将被重定向到授权页面)?

Also, how do I ensure the user authenticates before that page is displayed? Do I simply have my code redirect the user to the login page if they are not logged in? If so, how will OWIN handle the real redirect back to the client (if the user would be redirected to the authorization page once they login)?

最后,一旦这一切都配置正确,我是否仍然能够支持当前的 OAuth 工作流程,我允许客户端手动为令牌"API 传递他们的凭据?我之所以这么问是因为我们也有拥有自己的登录屏幕的移动应用,并且将使用 OAuth 进行连接(除了其他基于网络的客户端).

Finally, once this is all configured properly, will I still be able to support the current OAuth workflow I have of allowing clients to manually pass in their credentials for the "token" API? The reason I ask is because we also have mobile apps that have their own sign-in screen, and will be using OAuth to connect (in addition to other web-based clients).

推荐答案

我有一个 问题 与您的相似.

I had a question that turned out to be similar to yours.

所以,在网上搜索了一些之后,我通过搜索github获得了一些成功.显然,OAuthAuthorizationServerProvider 提供了 AuthorizeEndpoint 并且该方法应该用于嘿,你没有被授权,去登录你!"以及啊,好吧,你很酷,这是一个授权码.".我原以为 OAuthAuthorizationServerProvider 会有两个单独的方法,但它没有.这就解释了为什么在 github 上,我发现一些项目以一种相当奇特的方式实现了 AuthorizeEndpoint.我采用了这个.举个例子:

So, after quite some searching online, I got some success by searching github. Apparently, OAuthAuthorizationServerProvider offers AuthorizeEndpoint and that method should be used for both "Hey, you're not authorized, go log in you!" as well as for "Ahh, okay you're cool, here's an authorization code.". I had expected that OAuthAuthorizationServerProvider would have two separate methods for that, but it doesn't. That explains why on github, I find some projects that implement AuthorizeEndpoint in a rather peculiar way. I've adopted this. Here's an example:

public override async Task AuthorizeEndpoint(OAuthAuthorizeEndpointContext context)
{
    if (context.Request.User != null && context.Request.User.Identity.IsAuthenticated)
    {
        var redirectUri = context.Request.Query["redirect_uri"];
        var clientId = context.Request.Query["client_id"];

        var authorizeCodeContext = new AuthenticationTokenCreateContext(
            context.OwinContext, 
            context.Options.AuthorizationCodeFormat,
            new AuthenticationTicket(
                (ClaimsIdentity)context.Request.User.Identity,
                new AuthenticationProperties(new Dictionary<string, string>
                {
                    {"client_id", clientId},
                    {"redirect_uri", redirectUri}
                })
            {
                IssuedUtc = DateTimeOffset.UtcNow,
                ExpiresUtc = DateTimeOffset.UtcNow.Add(context.Options.AuthorizationCodeExpireTimeSpan)
            }));

        await context.Options.AuthorizationCodeProvider.CreateAsync(authorizeCodeContext);

        context.Response.Redirect(redirectUri + "?code=" + Uri.EscapeDataString(authorizeCodeContext.Token));
    }
    else
    {
        context.Response.Redirect("/account/login?returnUrl=" + Uri.EscapeDataString(context.Request.Uri.ToString()));
    }
    context.RequestCompleted();
}

来源:https://github.com/wj60387/WebApiOAUthBase/blob/master/OwinWebApiBase/WebApiOwinBase/Providers/OAuthServerProvider.cs

您在 /account/login 创建一个单独的登录页面.这样做是让用户登录.如果您的 WebAPI 使用基于 cookie 的身份验证,您只需再次将用户重定向回 AuthorizeEndpoint.如果您使用访问令牌,您的登录页面必须使用访问令牌向AuthorizeEndpoint"发出请求以获取授权代码.(不要将访问令牌提供给第三方.您的登录页面请求授权代码并将其发回.)换句话说,如果您使用访问令牌,则此流程中涉及两个客户端.

You create a separate login page at /account/login. What this does is sign the user in. If your WebAPI uses cookie-based authentication, you can just redirect the user back to the AuthorizeEndpoint again. If you use access tokens, your login page has to make a request to `AuthorizeEndpoint' with the access token to obtain an authorization code. (Don't give the access token to the third party. Your login page requests the authorization code and sends that back.) In other words, if you use access tokens then there are two clients involved in this flow.

这篇关于如何使 AuthorizeEndpointPath 在 ASP.NET Oauth 2.0 框架中工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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