Verify Access Token - Asp.Net Identity

2019-02-13 04:25发布

问题:

I'm using ASP.Net Identity to implement external logins. After user logins in with Google I get google's external access token. I then make a second api call to ObtainLocalAccessToken() which trades the external access token for a new local one.

ObtainLocalAccessToken() calls VerifyExternalAccessToken() which verifies the external access token with the provider by manually making http calls and parsing the user_id.

How can I leverage ASP.NET identity to remove the entire method VerifyExternalAccessToken()?

I believe that's what [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)] is for isn't it? I want to decorate ObtainLocalAccessToken() endpoint with that attribute and send the external_access_token in the header ({'Authorization' : 'Bearer xxx' }), and it should populate User.Identity without needing to manually verify the external access token? I believe that’s the purpose, however I cannot get it working. I send a valid external access token from google and it gets rejected with a 401.

I have this line in Startup.Auth btw:

 app.UseOAuthBearerTokens(new OAuthAuthorizationServerOptions
        {
            TokenEndpointPath = new PathString("/Token"),
            Provider = new ApplicationOAuthProvider(),
            AuthorizeEndpointPath = new PathString("/AccountApi/ExternalLogin"),
            AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
            AllowInsecureHttp = true
        });

Alternatively, it is possible to use "/Token" endpoint to trade an external access token for a local one? Which approach is correct?

回答1:

Studying the implementation by Taiseer Joudeh

the /ExternalLogin endpoint replaces the OWIN Authentication Challenge.

The AngularJS LoginController makes a call to the authService.obtainAccessToken when an externally authenticated user has not been found in Identity Provider:

        if (fragment.haslocalaccount == 'False') {
           ...
        }

        else {
            //Obtain access token and redirect to orders
            var externalData = { provider: fragment.provider,
                      externalAccessToken: fragment.external_access_token };
            authService.obtainAccessToken(externalData).then(function (response) {

                $location.path('/orders');

It uses the VerifyExternalAccessToken to perform a reverse lookup against Google and Facebook API's to get claim info for the bearer token.

        if (provider == "Facebook")
        {
            var appToken = "xxxxxx";
            verifyTokenEndPoint = string.Format("https://graph.facebook.com/debug_token?input_token={0}&access_token={1}", accessToken, appToken);
        }
        else if (provider == "Google")
        {
            verifyTokenEndPoint = string.Format("https://www.googleapis.com/oauth2/v1/tokeninfo?access_token={0}", accessToken);
        }
        else
        {
            return null;
        }

If token is found, it returns a new ASP.NET bearer token

        var accessTokenResponse = GenerateLocalAccessTokenResponse(user.UserName);

        return Ok(accessTokenResponse);

With [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)] the OWIN Middleware uses the external bearer token to access the 3rd party's Cookie and Register a new account (Or find existing).

OWIN Middleware cannot be configured to accept external bearer token instead of local authority tokens. External bearer tokens are only used for Authentication and Registration.