简体   繁体   中英

DotNetOpenAuth OAuth2 Accessing Extra Data

I'm using DotNetOpenAuth's OAuth2 library to handle authorization with another third party system. It all works great, except that the third party system is returning the UserId="testname" in the Response with the AccessToken.

I need that UserId because this third party API requires it as part of their API calls (ex: users/{userId}/account).

Using DotNetOpenAuth, I don't have access to the AccessToken response so I can't get the UserId out.

I'm calling: (_client is a WebServerClient) var state = _client.ProcessUserAuthorization(request);

state has my AccessToken, but not the extra data sent down. Based on the DotNetOpenAuth source code the UserId came in inside the library and I don't have any access.

Is there anyway to get that UserId out using DotNetOpenAuth? Or do I need to abandon DotNetOpenAuth and try something else?

You can access request and response data by implementing IDirectWebRequestHandler and assigning it to Channel . But with current implementation of DNOA, the only way I got it to work is by applying proxy pattern to an existing UntrustedWebRequestHandler class, this is because this particular handler passes a CachedDirectWebResponse , which has a response stream that could be read multiple times - once by your code to retrieve additional data, and later by downstream code to ProcessUserAuthorization() .

This is the code for custom IDirectWebRequestHandler :

public class RequestHandlerWithLastResponse : IDirectWebRequestHandler
    {
    private readonly UntrustedWebRequestHandler _webRequestHandler;
    public string LastResponseContent { get; private set; }

    public RequestHandlerWithLastResponse(UntrustedWebRequestHandler webRequestHandler)
        {
        if (webRequestHandler == null) throw new ArgumentNullException( "webRequestHandler" );
        _webRequestHandler = webRequestHandler;
        }

    public bool CanSupport( DirectWebRequestOptions options )
        {
        return _webRequestHandler.CanSupport( options );
        }

    public Stream GetRequestStream( HttpWebRequest request )
        {
        return _webRequestHandler.GetRequestStream( request, DirectWebRequestOptions.None );
        }

    public Stream GetRequestStream( HttpWebRequest request, DirectWebRequestOptions options )
        {
        return _webRequestHandler.GetRequestStream( request, options );
        }

    public IncomingWebResponse GetResponse( HttpWebRequest request )
        {
        var response = _webRequestHandler.GetResponse( request, DirectWebRequestOptions.None );

        //here we actually getting the response content
        this.LastResponseContent = GetResponseContent( response );

        return response;
        }

    public IncomingWebResponse GetResponse( HttpWebRequest request, DirectWebRequestOptions options )
        {
        return _webRequestHandler.GetResponse( request, options );
        }

    private string GetResponseContent(IncomingWebResponse response)
        {

        MemoryStream stream = new MemoryStream();
        response.ResponseStream.CopyTo(stream);

        stream.Position = 0;
        response.ResponseStream.Position = 0;

        using (var sr = new StreamReader(stream))
            {
            return sr.ReadToEnd();
            }
        }
    }

And this is how we apply it and get response data:

var h = new RequestHandlerWithLastResponse(new UntrustedWebRequestHandler()); ;
_client.Channel.WebRequestHandler = h;

var auth = _client.ProcessUserAuthorization( request );

//convert response json to POCO
var extraData = JsonConvert.DeserializeObject<MyExtraData>( h.LastResponseContent );

Just read the id straight from the request, line after your call to ProcessUserAuthorization , depending on how it is passed (body, query string). I don't see any reason to stop using the DNOA.

var auth = client.ProcessUserAuthorization();
if ( auth != null )
{
   // this is where you could still access the identity provider's request
   ...

Note that passing additional parameters together with the access token is rather uncommon and could lead to potential security issues. This is because the identity provider's response first gets to the user's browser and is then submitted to your server. The user could possibly alter the identity provider's response by keeping the access token but replacing the userid with any other valid userid.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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