How can I get an OAuth2 bearer token from the browser? - c#

I'm trying to get a bearer authentication token from a browser web page.
I'm using selenium and previously I could login to our URL and the bearer token was displayed in a form field. Now it has changed and the token is hidden. How can I extract that token and store into a variable?
This was my previous code (i know it's not great but I am not a developer by any means)..
IWebElement tokenField = getDriver().FindElement(By.XPath("/html/body/div[2]/div[2]/div[2]"));
string token = tokenField.Text;
restClient.Authenticator = new OAuth2AuthorizationRequestHeaderAuthenticator(token, "Bearer");
request.AddHeader("Accept", "application/json");
Any help would be appreciated. I am very new to OAuth2 and just security in general.

Usually you won't be able to find sensitive data like auth token displayed in the FE.
If the token is hidden and you cannot take it from FE or DOM, you can login using API calls and from there to get the token which can be used in the further requests.
If you're working within a development team, you can ask a dev to guide you with this and provide login url and other necessary stuff.

Related

Pass token using URL header

I have a code that authenticate using Azure AD
I'm using openIdConnect Lib to authenticate with azure AD.
The scenario as below:
user open the URL of the app.
the app redirect user to Azure AD to authenticate
get the id token & access token
then AzureActiveDirectoryAuthMiddleware get the context and continue the scenario
this scenario is happenning from the UI, i need to know if i need to pass step number 3 (id token & access token) from postman and the middleware will continue the flow, how i can do this flow?
because my app will be used from UI and from postman
Using c# owin
if you want to check/test the middleware(some REST endpoint) functionality using the tokens through Postman, then copy the AccessToken and open Postman, set the Authorization type as Bearer and add the AccessToken as BearerToken and test the REST call.
Please make sure that the token added should start with Bearer (example - Bearer xyzabc)

Sign out a user OneDrive API

I want to sign out a user in OneDrive API, I tried this, I sent the request:
var client = new RestClient("https://login.live.com/oauth20_logout.srf?client_id=762d0c10-xxxx-xxxx-xxxx-085a4a1743bc&redirect_uri=urn:ietf:wg:oauth:2.0:oob");
var request = new RestRequest(Method.GET);
request.AddHeader("Content-Type", "application/x-www-form-urlencoded");
IRestResponse response = client.Execute(request);
Console.WriteLine((int)response.StatusCode);
Console.WriteLine(response.IsSuccessful);
output:
302
False
my question is how to send a logout request
OAuth is inherently stateless so there is really nothing to "sign out" of. When you complete the OAuth flow you receive a token back. That token is used to authenticate the user every time you call the API. If you don't include the token in the Authorization header, the API will reject your request.
So to "sign out", simply wipe any stored access token values from your app's memory/storage and the app will no longer have access to that user's account.
I am afraid you did not follow the rules before performing the request:
Delete any cached access_token or refresh_token values you've
previously received from the OAuth flow.
Perform any sign out actions in your application (for example,
cleaning up local state, removing any cached items, etc.).
Only after can you make a call to the authorization web service using the url:
https://login.microsoftonline.com/common/oauth2/v2.0/logout?post_logout_redirect_uri={redirect-uri}
After removing the cookie, the browser will be redirected to the redirect URL you provided. When the browser loads your redirect page, no authentication query string parameters will be set, and you can infer the user has been logged out.

"invalid_grant" error from DocuSign token api from an Angular SPA

I'm using the below code to get access token and refresh token from docusign.
But I'm always getting the invalid-grant error. I'm pasting the code below.
[HttpGet("GetDocToken")]
[AllowAnonymous]
public async Task<IActionResult> getToken(string docCode)
{
var x = docCode.Length;
var client = new HttpClient();
var authCode=Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes("ced8998a-4387-4f30-9ab7-51c0d1af49bf:d7c3ccd4-22fa-4f18-a540-ddf11d8b2c9f"));
client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", authCode);
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/x-www-form-urlencoded"));
var requestContent = new FormUrlEncodedContent(new[] {
new KeyValuePair<string, string>("grant_type", "authorization_code"),
new KeyValuePair<string, string>("code", docCode),
new KeyValuePair<string, string>("redirect_uri", "http://localhost:4200/auth")
});
HttpResponseMessage response = await client.PostAsync("https://account-d.docusign.com/oauth/token", requestContent);
string resultContent = response.Content.ReadAsStringAsync().Result;
return Ok(response.Content.ReadAsStringAsync());
}
My assumption is that you have received the authentication code back from the DocuSign identity system and are trying to exchange it for an access token.
A couple of issues:
The docs incorrectly indicates that the redirect_uri should be included in the request. The Example Request in the docs does correctly show that the request should only include the grant_type and code parameters.
Note: While the OAuth standard, section 4.1 (d) does indicate that the redirect_url should be included, DocuSign usually does not include it.
My guess is that DocuSign will ignore the redirect_uri parameter, but you might want to try leaving it out.
Another issue is timing: The authorization code you receive back from DocuSign is only good for a minute or so. If you're not immediately using the authorization code (your code's docCode) then you'll get the Invalid Grant error.
Known good example software
I suggest that you also check out the known-good code example for C#. You can use a protocol peeker to see exactly what it is doing during the authentication.
Use a library
I also suggest that you look for an OAuth Authorization Code client library that you can use instead of rolling your own.
For example, are you setting and checking the state value? It's important to do that to stop CSRF attacks. See this article.
Added
It is also not clear to me that you are using the right value as the authorization code.
I believe the flow should be:
User presses "Authenticate with DocuSign" in the Angular app.
User's browser does a GET to the DocuSign authentication server. At this point, the browser is no longer running the Angular app.
User's browser and DocuSign Authentication server exchange HTML back and forth as the user authenticates with DocuSign.
The user completes the authentication process with DocuSign.
DocuSign sends a REDIRECT response to the browser, telling the browser to do a GET on the redirect url. The redirect (and the GET) include query parameters for code and state
Your SERVER (not the Angular app), receives the GET request.
Your server should:
Extract the code and state query parameters
Verify that state is the same as was sent in step 2.
Makes the POST request to DocuSign to exchange the authorization code for an access token.
RESPONDS to the browser with the Angular program.
The Angular program is now once again running on the browser.
Use Implicit Grant
Your other option is to use Implicit Grant. That way you don't need a server component. With Implicit Grant, your Angular program handles the flow.

Validating an access token in my ASP.NET Web API

I have a mobile client (app) letting the user authenticate with google. So, the client receives an access token and some info (name, email etc) from google. Works fine!
I also created an ASP.NET Web API that the mobile app should comunicate with. On the client side I am adding the token to the HttpClient with:
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "pretty_long_access_token_separated_by_two_dots");
Question 1: I'm trying to "decode" the access token on this site (to make sure it's all right): https://jwt.io/
The header and the payload is all right, but it seems like it's an "invalid signature" (says in the bottom). Should I worry about this?
On the server side, I added this to the Configuration method in the Startup class:
app.UseJwtBearerAuthentication( new JwtBearerAuthenticationOptions
{
AuthenticationMode = AuthenticationMode.Active,
AllowedAudiences = new List<string> {"my_client_id"},
IssuerSecurityTokenProviders = new IIssuerSecurityTokenProvider[]
{
new SymmetricKeyIssuerSecurityTokenProvider(#"https://accounts.google.com/", "my_client_secret")
},
});
The only thing I want to do with the token, on my server side, is making sure that only validated users from my app should be able to access my API-controller.
Question 2: Is UseJwtBearerAuthentication the right thing for me, or am I going in the wrong direction?
My problem is, I constantly get 401, unauthorized, when trying to access my WEB API controller.
If I am on the right track, I can try to explain more about the server side setup...
Any helt would be very appreciated!
If you are using a JWT token then you will need JWT instead of Bearer
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("JWT", "pretty_long_access_token_separated_by_two_dots");
The signature is used to validate the token as authentic and is therefore only required by the authentication server. If Google is your authentication server, then there should be an API endpoint you can call from your server to verify that the token is valid.
If your server is issuing the JWT token, then you will need to check that the token is valid by decoding the signature using the secret that was used to create it in the first place
If Google is issuing the JWT and you want your server to be able to self validate it, then you need to use another encryption type such as RS256 which will allow you to validate the signature using a public key issued by Google (I have no idea if they provide this method or not)
The reason https://jwt.io/ cannot validate your signature is because it was signed using a secret code. If you have this secret code then you are able to paste it into the textbox in the bottom right. If the secret is correct, and the token hasn't expired, it will show as being a valid JWT token.

Get authorization code from refreshtoken

I am using dotnetopenauth and working with google api. My problem is to get authorization code from my saved refresh token. If i can get that code then i can get accesstoken. i want to get that code not accesstoken directly. I was unable to find any method or url of end point which can return me authorization code from my refresh token. Thanx in advance
I think you have the OAuth 2 flow confused. Authorization codes do not come from refresh tokens. It's the other way around: you get refresh tokens in exchange for a one-time-use of your authorization code. Access tokens are obtained in any of three ways
In exchange for a refresh token.
In the initial exchange for the authorization code that returns both a refresh token and an access token.
OR, if you're using the implicit grant type instead of the authorization code flow, you get the access token in the url #fragment in response to the user's authorization redirect, but this only applies to JavaScript executing on the browser since fragments are not sent to web servers.

Categories