Using SharePoint 2013 TokenHelper class when there is no HttpContext.Current
-
10-12-2019 - |
Question
SharePoint 2013 Apps in Visual Studio have a TokenHelper class that simplifies using OAuth to connect to a SharePoint 2013 ClientContext. I am using this class to remotely connect to a SharePoint 2013 (on Office 365).
I can use the TokenHelper.GetClientContextWithAuthorizationCode method to get the ClientContext with the OAuth authorization code when running in a web application that has an HttpContext.Current. However, if I use this same code in a console application or other context where there is no HttpContext.Current, the remote SharePoint 2013 server returns (400) Bad Request.
I've narrowed the issue down to the Microsoft.IdentityModel.S2S.Protocols.OAuth2.OAuth2S2SClient.Issue() method. When there is an HttpContext, it works, but without it gets the (400) Bad Request error.
I have tried using the Moq framework to fake an HttpContext, but that doesn't work either.
The failure occurs in the TokenHelper.GetAccessToken method here:
OAuth2S2SClient client = new OAuth2S2SClient();
OAuth2AccessTokenResponse oauth2Response;
try
{
oauth2Response =
client.Issue(AcsMetadataParser.GetStsUrl(realm), oauth2Request) as OAuth2AccessTokenResponse;
}
Any ideas?
Solution
I was finally able to figure out what I was doing wrong:
1) The Authorization Code returned when creating the OAuth connection is only good for that browser session. Thus why I couldn't reuse that authorization code later in back end services or in new browser sessions.
2) On the redirect page, I used the Authorization Code returned to create a new Access Token. From the Access Token I could retrieve the Refresh Token.
3) The Refresh Token is what I can store and reuse later to create client contexts from back end code or new browser sessions.
So, in a nutshell, to reuse the OAuth token, you have to use the Refresh Token, not the Authorization Code.