简体   繁体   English

如何使AuthorizeEndpointPath在ASP.NET Oauth 2.0框架中工作

[英]How do I make the AuthorizeEndpointPath work in ASP.NET Oauth 2.0 framework

I currently have a website where I am trying to implement the OAuth server framework. 我目前有一个网站,我正在尝试实施OAuth服务器框架。 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 Forms(非MVC)和Web API 2的组合。出于我想要做的目的,我们无法改变系统的整体架构。

So far, I have OAuth working via the Web API for validating clients, generating access tokens, and handling refresh tokens. 到目前为止,我让OAuth通过Web 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. 这将允许我们授予对我们的应用程序的访问权限,以便集成工具可以访问我们的API,而无需在本地存储用户凭据。

My understanding of how it should function is the following: 我对它应该如何运作的理解如下:

  1. User is directed to the AuthorizeEndpointPath that I define in the Startup.Auth file 用户将被定向到我在Startup.Auth文件中定义的AuthorizeEndpointPath
  2. User either sees a login page (if they don't already have an authentication cookie for the website), or they see a special page where they have to grant permission to access the account (similar to what Google has) 用户要么看到登录页面(如果他们还没有网站的身份验证cookie),要么他们看到一个特殊页面,他们必须授予访问该帐户的权限(类似于Google所拥有的)
  3. Once the user clicks the "grant" button, the OWIN middleware will process the request, and redirect them back to the original client URL that requested access 一旦用户单击“授权”按钮,OWIN中间件将处理该请求,并将它们重定向回请求访问的原始客户端URL

However, after all of my configuration, whenever I access the AuthorizeEndpointPath directly, the "grant access permission" page is never actually displayed. 但是,在我的所有配置之后,每当我直接访问AuthorizeEndpointPath时,都不会实际显示“授予访问权限”页面。

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()
            };

Currently the "AuthorizeEndpointPath" property maps to an actual page, where I ask the user confirmation, but that page is not being displayed at all 目前,“AuthorizeEndpointPath”属性映射到实际页面,我要求用户确认,但该页面根本没有显示

Through debugging, I can see the framework hits the following method even before the authorization page would be loaded 通过调试,我甚至可以在加载授权页面之前看到框架遇到以下方法

ValidateClientRedirectUri(OAuthValidateClientRedirectUriContext context)

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. 如果我调用context.Validated();,则会立即重定向用户,而不显示授权页面。 If don't "validate" the redirect URI, then a blank page is displayed indicating an "invalid_request". 如果不“验证”重定向URI,则显示空白页面,指示“invalid_request”。

So the big question is how do I actually make OWIN display my custom authorization page? 所以最大的问题是如何让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)? 如果是这样,OWIN将如何处理真正的重定向回客户端(如果用户登录后将被重定向到授权页面)?

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? 最后,一旦正确配置完毕,我是否仍然能够支持当前的OAuth工作流程,允许客户端手动传递“令牌”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). 我问的原因是因为我们也有自己的登录屏幕的移动应用程序,并将使用OAuth连接(除了其他基于Web的客户端)。

I had a question that turned out to be similar to yours. 我有一个问题 ,结果与你的相似。

So, after quite some searching online, I got some success by searching github. 因此,经过网上搜索,我通过搜索github获得了一些成功。 Apparently, OAuthAuthorizationServerProvider offers AuthorizeEndpoint and that method should be used for both "Hey, you're not authorized, go log in you!" 显然, OAuthAuthorizationServerProvider提供AuthorizeEndpoint并且该方法应该用于“嘿,你没有被授权,请登录你!” 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. 我原以为OAuthAuthorizationServerProvider会有两个不同的方法,但事实并非如此。 That explains why on github, I find some projects that implement AuthorizeEndpoint in a rather peculiar way. 这就解释了为什么在github上,我发现一些项目以一种相当特殊的方式实现AuthorizeEndpoint 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();
}

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

You create a separate login page at /account/login . 您可以在/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. 这样做是为用户签名。如果您的WebAPI使用基于cookie的身份验证,您可以再次将用户重定向回AuthorizeEndpoint If you use access tokens, your login page has to make a request to `AuthorizeEndpoint' with the access token to obtain an authorization code. 如果您使用访问令牌,则您的登录页面必须使用访问令牌向“AuthorizeEndpoint”发出请求以获取授权码。 (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. (不要将访问令牌提供给第三方。您的登录页面请求授权代码并将其发回。)换句话说,如果您使用访问令牌,则此流程中涉及两个客户端。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM