How to store access token? (Oauth 2, Auth code flow) - security

From what i understand the purpose of the Authorization Code flow is to exchange the auth code for access token. This exchange happens between the server which serves the page and authorization server so that the actual access token is not exposed to the client user.
How should the page server store the access token once it is obtained? I was learning from a Pluralsight example in which there is this part of code:
public static HttpClient GetClient()
{
HttpClient client = new HttpClient();
var accessToken = RequestAccessTokenAuthorizationCode();
client.SetBearerToken(accessToken);
client.BaseAddress = new Uri(IdentityConstants.API);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
return client;
}
private static string RequestAccessTokenAuthorizationCode()
{
// did we store the token before?
var cookie = HttpContext.Current.Request.Cookies.Get("ClientMVCCookie.AuthCode");
if (cookie != null && cookie["access_token"] != null && !string.IsNullOrEmpty(cookie["access_token"]))
{
return cookie["access_token"];
}
// no token found - request one
// we'll pass through the URI we want to return to as state
var state = HttpContext.Current.Request.Url.OriginalString;
var authorizeRequest = new IdentityModel.Client.AuthorizeRequest(
IdentityConstants.AuthEndoint);
var url = authorizeRequest.CreateAuthorizeUrl(IdentityConstants.MVCClientSecret, "code", "management secret",
IdentityConstants.MVCAuthCodeCallback, state);
HttpContext.Current.Response.Redirect(url);
return null;
}
}
This will cause each request to check if there is an access token stored in the cookie. If not then the flow will be initiated. The callback looks like this:
public class CallbackController : Controller
{
// GET: STSCallback
public async Task<ActionResult> Index()
{
// get the authorization code from the query string
var authCode = Request.QueryString["code"];
// with the auth code, we can request an access token.
var client = new TokenClient(
IdentityConstants.TokenEndoint,
"mvc_client_auth_code",
IdentityConstants.MVCClientSecretAuthCode);
var tokenResponse = await client.RequestAuthorizationCodeAsync(
authCode,
IdentityConstants.MVCAuthCodeCallback);
// we save the token in a cookie for use later on
var cookie = Response.Cookies["ClientMVCCookie.AuthCode"];
cookie.Expires = DateTime.Now.AddMinutes(1);
cookie["access_token"] = tokenResponse.AccessToken;
// get the state (uri to return to)
var state = Request.QueryString["state"];
// redirect to the URI saved in state
return Redirect(state);
}
}
Doesn't storing the access token in the cookie defeath the whole purpose of the authorization code flow? The cookie will be transmitted to the client browser thus exposing it to the client? Am i missing something? It this is not the correct way to store the token, how should it be stored?

The client, in OAuth terminology, is the component that makes requests to the resource server, in your case, the client is the server of a web application (NOT the browser).
Therefore, the access token should be stored on the web application server only. It should not be exposed to the browser, and it doesn't need to, because the browser never makes any direct requests to the resource server. It talks to the web application server instead, which in turn makes requests to the resource server using the access token.
How the browser authenticates itself with the web application server has nothing to do with OAuth 2.0. For example, it might be a regular session cookie, and the web application server might associate each session or each user with an access token.
The token request, which exchanges the authentication code for an access token, is done by the web application server, and the web application server should authenticate itself with the authorization server (e.g., using a shared client_secret).
Authorization code flow ensures that the client can be authenticated, which protects against malicious clients posing as legitimate clients. Not all web application clients have a server component, and in some cases, requests to the resource server are made directly by JavaScript code in the browser. In such situations, the browser is the client, and the access token must be stored by the browser (in a JavaScript variable, local storage or a cookie). In this case, the client cannot be authenticated (but a reasonable amount of security may be achieved by using TLS and the server redirecting only to registered endpoint URLs).
Recommended reading regarding OAuth 2.0 security: https://www.rfc-editor.org/rfc/rfc6819#section-4.3.3 (RFC 6819)

The cookie is never exposed to the browser. It is part of the response returned from the authorization server to the client, which itself is a server, not a browser. The CallbackController, which implements the redirection endpoint, extracts the cookie from the response.
The cookie is never passed on to the browser. How the browser authenticates itself with the client's application server is not shown in your sample code, and it is not part of OAuth.
The authorization server could store the token in the request body (e.g., in JSON format) rather than in a cookie. However, this makes no difference, because the client can see and process the entire response anyway.
For details, see my other answer: https://stackoverflow.com/a/44655679/2279059
Side note: The CallbackController uses state to store a final URL to redirect the browser to. This is non-standard but works. However, state is actually meant to protect the redirection endpoints against CSRF attacks. The CallbackController does not validate state but blindly redirects to whatever URL was given. Probably this detail was left out, because the code was meant as an example. However, it shows that this code is probably not entirely production-ready.

If you are going to request a rest resource from the browser, the flow you need is Implicit Grant. Check this Auth0 post to decide between the flows https://auth0.com/docs/api-auth/which-oauth-flow-to-use. If you want to use the access token from server you should store the Authorization code and generate an access token every time you need it, access token is not intended to live more than 5 minutes, you don't need to store it

Related

Next.js Authentication with JWT

I am moving a project from React to Next.js and was wondering if the same authentication process is okay. Basically, the user enters their username and password and this is checked against database credentials via an API (Node.js/Express). So, I am not using Next.js internal api functionality, but a totally decoupled API from my Next.js project.
If the login credentials are correct, a JWT token is sent back to the client. I wanted to store that in local storage and then redirect the user. Any future HTTP requests will send the token in the header and check it is valid via the API. Is this okay to do? I ask because I see a lot of Next.js auth using cookies or sessions and don't know if that is the 'standard' approach which I should rather adopt.
My answer is purely based on my experiences and things I read. Feel free to correct it if I happened to be wrong.
So, my way is to store your token in HttpOnly cookie, and always use that cookie to authorize your requests to the Node API via Authorization header. I happen to also use Node.js API in my own project, so I know what's going on.
Following is an example of how I usually handle authentication with Next.js and Node.js API.
In order to ease up authentication problems, I'm using Next.js's built in getServerSideProps function in a page to build a new reusable higher order component that will take care of authentication. In this case, I will name it isLoggedIn.
// isLoggedIn.jsx
export default (GetServerSidePropsFunction) => async (ctx) => {
// 1. Check if there is a token in cookies. Let's assume that your JWT is stored in 'jwt'.
const token = ctx.req.cookies?.jwt || null;
// 2. Perform an authorized HTTP GET request to the private API to check if the user is genuine.
const { data } = await authenticate(...); // your code here...
// 3. If there is no user, or the user is not authenticated, then redirect to homepage.
if (!data) {
return {
redirect: {
destination: '/',
permanent: false,
},
};
}
// 4. Return your usual 'GetServerSideProps' function.
return await GetServerSidePropsFunction(ctx);
};
getServerSideProps will block rendering until the function has been resolved, so make sure your authentication is fast and does not waste much time.
You can use the higher order component like this. Let's call this one profile.jsx, for one's profile page.
// profile.jsx
export default isLoggedIn(async (ctx) => {
// In this component, do anything with the authorized user. Maybe getting his data?
const token = ctx.req.cookies.jwt;
const { data } = await getUserData(...); // don't forget to pass his token in 'Authorization' header.
return {
props: {
data,
},
},
});
This should be secure, as it is almost impossible to manipulate anything that's on server-side, unless one manages to find a way to breach into your back-end.
If you want to make a POST request, then I usually do it like this.
// profile.jsx
const handleEditProfile = async (e) => {
const apiResponse = await axios.post(API_URL, data, { withCredentials: true });
// do anything...
};
In a POST request, the HttpOnly cookie will also be sent to the server, because of the withCredentials parameter being set to true.
There is also an alternative way of using Next.js's serverless API to send the data to the server. Instead of making a POST request to the API, you'll make a POST request to the 'proxy' Next.js's serverless API, where it will perform another POST request to your API.
there is no standard approach. You should be worried about security. I read this blog post: https://hasura.io/blog/best-practices-of-using-jwt-with-graphql/
This is a long but an awesome blog post. everyhing I post here will be quoted from there:
If a JWT is stolen, then the thief can keep using the JWT. An API
that accepts JWTs does an independent verification without depending
on the JWT source so the API server has no way of knowing if this was
a stolen token! This is why JWTs have an expiry value. And these
values are kept short. Common practice is to keep it around 15
minutes.
When server sends you the token, you have to store the JWT on the client persistently.
Doing so you make your app vulnerable to CSRF & XSS attacks, by
malicious forms or scripts to use or steal your token. We need to save our JWT token somewhere so that we can forward it to our API as a header. You might be tempted to persist it in localstorage; don’t do it! This is prone to XSS attacks.
What about saving it in a cookie?
Creating cookies on the client to save the JWT will also be prone to XSS. If it can be read on the client from Javascript outside of
your app - it can be stolen. You might think an HttpOnly cookie
(created by the server instead of the client) will help, but cookies
are vulnerable to CSRF attacks. It is important to note that HttpOnly
and sensible CORS policies cannot prevent CSRF form-submit attacks and
using cookies requires a proper CSRF mitigation strategy.
Note that a SameSite cookie will make Cookie based approaches safe
from CSRF attacks. It might not be a solution if your Auth and API
servers are hosted on different domains, but it should work really
well otherwise!
Where do we save it then?
The OWASP JWT Cheatsheet and OWASP ASVS (Application Security
Verification Standard) prescribe guidelines for handling and storing
tokens.
The sections that are relevant to this are the Token Storage on Client
Side and Token Sidejacking issues in the JWT Cheatsheet, and chapters
3 (Session Management) and 8 (Data Protection) of ASVS.
From the Cheatsheet, "Issue: Token Storage on the Client Side":
Automatically sent by the browser (Cookie storage).
Retrieved even if the browser is restarted (Use of browser localStorage container).
Retrieved in case of XSS issue (Cookie accessible to JavaScript code or Token stored in browser local/session storage).
"How to Prevent:"
Store the token using the browser sessionStorage container.
Add it as a Bearer HTTP Authentication header with JavaScript when calling services.
Add fingerprint information to the token.
By storing the token in browser sessionStorage container it exposes
the token to being stolen through a XSS attack. However, fingerprints
added to the token prevent reuse of the stolen token by the attacker
on their machine. To close a maximum of exploitation surfaces for an
attacker, add a browser Content Security Policy to harden the
execution context.
"FingerPrint"
Where a fingerprint is the implementation of the following guidelines
from the Token Sidejacking issue: This attack occurs when a token has been intercepted/stolen by an attacker and they use it to gain access to the system using targeted user identity.
"How to Prevent":
A way to prevent it is to add a "user context" in the token. A user context will be composed of the following information:
A random string will be generated during the authentication phase. It will be sent to the client as a hardened cookie (flags: HttpOnly +
Secure + SameSite + cookie prefixes).
A SHA256 hash of the random string will be stored in the token (instead of the raw value) in order to prevent any XSS issues allowing
the attacker to read the random string value and setting the expected
cookie.

JWT Token Storage

I have been going through some of my .NET Core2 services and adding some JWT authentication to them to provide some basic security.
I created a new ProvisioningService which has an endpoint that builds a token and returns it:
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["Jwt:Key"]));
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var token = new JwtSecurityToken(_config["Jwt:Issuer"],
_config["Jwt:Issuer"],
claims,
expires: DateTime.Now.AddMinutes(30),
signingCredentials: creds);
return new JwtSecurityTokenHandler().WriteToken(token);
I altered one of my existing services (which I'll refer to as TestService) by adding AddAuthentication in the StartUp. The endpoint for this call has the [HttpPost(), Authorize] attributes. I deployed these changes to my Test server.
When I call TestService/api/updateSomething I am returned a 401 Unauthorized as expected. On my local machine, I create a new token via ProvisioningService/api/buildToken and add the token from the response to my TestService call via the Authorization header. To my surprise...this worked.
Why does my TestService (on a completely different server) view a token created on my local machine as a valid token and allow the call to work? I was expecting this to return the same 401 because I assumed this token was going to be invalid on my Test server. My inexperience with JWT is probably showing....but I am not understanding how these tokens are being stored/shared between servers.
I failed to understand that the token itself has what it needs to authorize itself after it is decrypted. This question is no longer needed.

Auth0 authentication of single-page-app on a different domain than the api

I'm trying add Auth0 authentication to my single-page-app. My app is running under a domain, say app.mycompany.com, whereas the api used by this app is running under a different domain, say api.mycompany.com.
I'm aware of this thread:
Single Sign On (SSO) solution/architecture for Single Page App (SPA)
and the auth0 articles and github repositories linked by here. But I have a feeling that my scenario is slightly simpler, as I don't necessarily want to have single-sign-on between several different single-page-apps. For a start I just want the seperation between the API and the app.
Here is what I have tried already:
I already started from the article React Login With Auth0 and downloaded the starter project. I can surely login without problems and it will leave me with an id_token in my localStorage containing a JWS issued by Auth0.
I can also login directly on api.mycompany.com (my FeathersJS API application) and I can see that during the OAuth redirecting process, the id_token token is magically translated to a feathers-jwt token issued by my Feathers application containing the internal ID of the user-object matching the auth0-ID. I also have implemented the logic used to map from the Auth0-ID to my internal ID. Furthermore all my Feathers hooks such as validation of token and population of the user are working.
What I cannot figure out is how to alter the react-application running under app.mycompany.com with an Auth0-token in localStorage, so that this token is translated to a feathers-jwt token by api.mycompany.com, in such a way that all succeeding API-calls automatically has the feathers-jwt token included so the API can validate the user and return the right data.
Any suggestions on how to proceed will be greatly appreciated.
A couple of more background details:
The api is built on node.js and featherjs (which basically is an extension of Express)
The single-page-app is built on ReactJS and is served by a simple Express server, but it could be served by any server that can serve static files over http. The single-page-app makes http-requests to the api to read data and perform operations.
The api has the following lines of code taking care of the authentication:
const authentication = require('feathers-authentication');
const Auth0Strategy = require('passport-auth0').Strategy;
app.configure(authentication({
local:false,
token: {
secret: 'mysecret',
payload: ['email', 'auth0Nickname'],
issuer: 'mycompany'
},
idField: 'id',
shouldSetupSuccessRoute: false,
auth0: {
strategy: Auth0Strategy,
domain: 'mycompany.eu.auth0.com',
'clientID': 'xxx',
'clientSecret': 'yyy'
}
}));
I had exactly the same problem as you, I wanted to authenticate a user from a single page application, calling the API located on an other server.
The official auth0 example is a classic Express web application that does authentication and renders html page, but it's not a SPA connected to an API hosted on an other domain.
Let's break up what happens when the user authenticates in this example:
The user makes a request calling /auth/auth0 route
The user is automatically redirected to the Auth0 authentication process (Auth0 login form to choose the provider and then the provider login screen)
The user is redirected to /auth/success route
/auth/success route redirects to the static html page public/success.html, also sending a jwt-token cookie that contains the user's token
Client-side, when public/success.html loads, Feathers client authenticate() method reads the token from the cookie and saves it in the local storage.
From now, the Feathers client will authenticate the user reading the cookie from the local storage.
I tried to adapt this scenario to a single-page application architecture, implementing the following process:
From the SPA, call the authentication API with a source query string parameter that contains the SPA URL. For example: http://my-api.com/auth/auth0?source=http://my-spa.com
Server-side, in /auth/auth0 route handler, create a cookie to store that URL
After a successful login, read the source cookie to redirect the user back to the SPA, sending the JWT token in a cookie.
But the last step didn't work because you can't set a cookie on a given domain (the API server domain) and redirect the user to an other domain! (more on this here on Stackoverflow)
So actually I solved the problem by:
server-side: sending the token back to the client using the URL hash.
client-side: create a new html page that reads the token from the URL hash
Server-side code:
// Add a middleware to write in a cookie where the user comes from
// This cookie will be used later to redirect the user to the SPA
app.get('/auth/auth0', (req, res, next) => {
const { origin } = req.query
if (origin) {
res.cookie(WEB_CLIENT_COOKIE, origin)
} else {
res.clearCookie(WEB_CLIENT_COOKIE)
}
next()
})
// Route called after a successful login
// Redirect the user to the single-page application "forwarding" the auth token
app.get('/auth/success', (req, res) => {
const origin = req.cookies[WEB_CLIENT_COOKIE]
if (origin) {
// if there is a cookie that contains the URL source, redirect the user to this URL
// and send the user's token in the URL hash
const token = req.cookies['feathers-jwt']
const redirectUrl = `${origin}/auth0.html#${token}`
res.redirect(redirectUrl)
} else {
// otherwise send the static page on the same domain.
res.sendFile(path.resolve(process.cwd(), 'public', 'success.html'))
}
})
Client-side, auth0.html page in the SPA
In the SPA, I created a new html page I called auth0.html that does 3 things:
it reads the token from the hash
it saves it in the local storage (to mimic what the Feathers client does)
it redirects the user to the SPA main page index.html
html code:
<html>
<body>
<script>
function init() {
const token = getToken()
if (!token) {
console.error('No auth token found in the URL hash!')
}
// Save the token in the local storage
window.localStorage.setItem('feathers-jwt', token)
// Redirect to the single-page application
window.location.href = '/'
}
// Read the token from the URL hash
function getToken() {
const hash = self.location.hash
const array = /#(.*)/.exec(hash)
if (!array) return
return array[1]
}
init()
</script>
</body>
</html>
And now in the SPA I can use the Feathers client, reading the token from the local storage when the app starts.
Let me know if it makes sense, thank you!
If you haven't done so, you should follow this article (React Login with Auth0) to implement the authentication on your React application. If you already tried to follow it, update your question with specific issues you faced.
Even though you currently not need SSO, the actual implementation of the authentication in your application will not vary much. By using Auth0 enabling SSO across your apps is mostly enabling configuration switches.
Finally for a full reference with all the theory behind the security related aspects of your exact scenario check:
Auth0 Architecture Scenarios: SPA + API
Update:
The full scenario I linked too covers the most comprehensive scenarios where an API is accessed by a multitude of client applications that may even be developed by third-parties that do not own the protected API, but want to access the data behind it.
It does this by leveraging recent features that are currently only available in the US region and that at a very high level can be described as an OAuth 2.0 authorization server delivered as a service.
Your particular scenario is simpler, both the API and client application are under control of the same entity, so you have another option.
Option 1 - Leverage the API authorization through Auth0 US region only (for now)
In this situation your client application, at authentication time, would receive an id_token that would be used to know the currently authenticated user and would also receive an access_token that could be used to call the API on behalf of the authenticated user.
This makes a clear separation between the client application and the API; the id_token is for client application usage and the access_token for API usage.
It has the benefit that authorization is clearly separated from authentication and you can have a very fine-grained control over authorization decisions by controlling the scopes included in the access token.
Option 2 - Authenticate in client application and API in the same way
You can deploy your client application and API separately, but still treat them from a conceptual perspective as the same application (you would have one client configured in Auth0 representing both client-side and API).
This has the benefit that you could use the id_token that is obtained after authentication completes to know who the user was on the client-side and also as the mechanism to authenticate each API request.
You would have to configure feathers API to validate the Auth0 id_token as an accepted token for accessing the API. This means that you don't use any feathers based on authentication on the API, that is, you just accept tokens issued by Auth0 to your application as the way to validate the access.

Web API 2 OWIN Bearer Token purpose of cookie?

I am trying to understand the new OWIN Bearer Token authentication process in the Single Page App template in MVC 5. Please correct me if I'm wrong, for the OAuth password client authentication flow, Bearer Token authentication works by checking the http authorization request header for the Bearer access token code to see if a request is authenticated, it doesn't rely on cookie to check if a particular request is authenticated.
According to this post:
OWIN Bearer Token Authentication with Web API Sample
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
using (IdentityManager identityManager = _identityManagerFactory.CreateStoreManager())
{
if (!await identityManager.Passwords.CheckPasswordAsync(context.UserName, context.Password))
{
context.SetError("invalid_grant", "The user name or password is incorrect.");
return;
}
string userId = await identityManager.Logins.GetUserIdForLocalLoginAsync(context.UserName);
IEnumerable<Claim> claims = await GetClaimsAsync(identityManager, userId);
ClaimsIdentity oAuthIdentity = CreateIdentity(identityManager, claims,
context.Options.AuthenticationType);
ClaimsIdentity cookiesIdentity = CreateIdentity(identityManager, claims,
_cookieOptions.AuthenticationType);
AuthenticationProperties properties = await CreatePropertiesAsync(identityManager, userId);
AuthenticationTicket ticket = new AuthenticationTicket(oAuthIdentity, properties);
context.Validated(ticket);
context.Request.Context.Authentication.SignIn(cookiesIdentity);
}
}
The GrantReourceOwnerCredentials function not only compose the ticket with this line: context.Validated(ticket); but it also compose a cookie identity and set it to the cookie with this line: context.Request.Context.Authentication.SignIn(cookiesIdentity);
So my questions are, what is the exact purpose of the cookie in this function? Shouldn't the AuthenticationTicket be good enough for authentication purpose?
In the SPA template there are actually two separate authentication mechanisms enabled- cookie authentication and token authentication. This enables authentication of both MVC and Web API controller actions, but requires some additional setup.
If you look in the WebApiConfig.Register method you'll see this line of code:
config.SuppressDefaultHostAuthentication();
That tells Web API to ignore cookie authentication, which avoids a host of problems which are explained in the link you posted in your question:
"...the SPA template enables application cookie middleware as active mode as well in order to enable other scenarios like MVC authentication. So Web API will still be authenticated if the request has session cookie but without a bearer token. That’s probably not what you want as you would be venerable to CSRF attacks for your APIs. Another negative impact is that if request is unauthorized, both middleware components will apply challenges to it. The cookie middleware will alter the 401 response to a 302 to redirect to the login page. That is also not what you want in a Web API request."
So now with the call to config.SuppressDefaultHostAuthentication() Web API calls that require authorization will ignore the cookie that is automatically sent along with the request and look for an Authorization header that begins with "Bearer". MVC controllers will continue to use cookie authentication and are ignorant of the token authentication mechanism as it's not a very good fit for web page authentication to begin with.
The existence of the cookie also left me puzzled, since it clearly is not necessary in a bearer token authentication scenario... In this post the author dissects the individual accounts template, and has the following to say about the cookie:
The method also sets an application cookie. I don’t see a good reason for that.
My guess is that the authors of the template wanted to show examples of different kinds of authentication logic, and in this particular case they wanted to show how the authentication information could be stored in both the bearer token authentication JSON payload, as well as in a standard authentication cookie.
The fact that the JSON authentication payload is set to also include an additional (unnecessary) unencrypted property (the user id), in addition to the encrypted ticket, seems to support this theory:
var properties = CreateProperties(user.UserName);
var ticket = new AuthenticationTicket(oAuthIdentity, properties);
It seems that the authors of the template wanted to provide some useful examples, rather than the bare minimum needed to achieve bearer token authentication. This is also mentioned in the linked post above.
The cookie has one important purpose. Its value contains the bearer token which can be extracted by client-side javascript on your pages. This means that if the user hits F5 or refreshes the page, the cookie will typically persist. Your client-side javascript can then grab the bearer token from the cookie when the page reloads.

How do you call an authenticated ServiceStack service once the client is authenticated using OAuth?

Lets say I have a web client (i.e. MVC 4 client) that authenticates users using an oAuth provider (i.e. Facebook, Google etc).
I want to call another web service in my client logic, and that web service also authenticates with oAuth providers.
What would the web service request look like from the client? What do I need to pass to the web service?
I suggest you review this question, How do I authorize access to ServiceStack resources using OAuth2 access tokens via DotNetOpenAuth?. The poster provided his final solution, including a link to a sample solution, which he has graciously open sourced. The client side code, for his solution, looks like this:
// Create the ServiceStack API client and the request DTO
var apiClient = new JsonServiceClient("http://api.mysite.com/");
var apiRequestDto = new Shortlists { Name = "dylan" };
// Wire up the ServiceStack client filter so that DotNetOpenAuth can
// add the authorization header before the request is sent
// to the API server
apiClient.LocalHttpWebRequestFilter = request => {
// This is the magic line that makes all the client-side magic work :)
ClientBase.AuthorizeRequest(request, accessTokenTextBox.Text);
}
// Send the API request and dump the response to our output TextBox
var helloResponseDto = apiClient.Get(apiRequestDto);
Console.WriteLine(helloResponseDto.Result);
A similar solution is provided here: https://stackoverflow.com/a/13791078/149060 which demonstrates request signing as per OAuth 1.0a
var client = new JsonServiceClient (baseUri);
client.LocalHttpWebRequestFilter += (request) => {
// compute signature using request and a previously obtained
// access token
string authorization_header = CalculateSignature (request, access_token);
request.Headers.Add ("Authorization", authorization_header);
};
var response = client.Get<MySecuredResponse> ("/my/service");
You will, of course, need to adjust to fit the requirements of your OAuth providers, i.e. signing, token, etc.

Resources