AuthorizationCodeProvider: Create is never called, how do I generate the authorization code?

后端 未结 1 507
挽巷
挽巷 2021-01-13 12:20

I\'m setting up my own OAuth2 server. So far, I have succesfully implemented GrantResourceOwnerCredentials in my implementation of OAuthAuthorizationServe

相关标签:
1条回答
  • 2021-01-13 12:51

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

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

    As for my remaining three questions:

    1. Right now, anybody can request an authorization code, the client_id is ignored. ValidateClientAuthentication is apparently not hit as part of AuthorizeEndpoint. How do I obtain ClientId in AuthorizeEndpoint?

    Answer: You have to implement `ValidateClientAuthentication'.

    1. The authorization code is not coupled to a client. Anyone who intercepts the code could use it. How do I obtain the ClientId in AuthorizationCodeProvider.Create so that I can store it with the code?

    Answer: OAuthAuthorizationServerProvider takes care of this. As long as you set "client_id" in the ticket, it will check that the client that requests an access token for the authorization code is the same.

    1. The authorization code is not coupled to a user at all, it's an empty ClaimsIdentity. How do I put a user-login page in between and in AuthorizeEndpoint obtain the ClaimsIdentity for the logged-in user?

    Answer: You create a separate login page. What this does is sign the user in. If your WebAPI uses cookie-based authentication, you can just redirect the user 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.

    0 讨论(0)
提交回复
热议问题