I'm trying to connect my ASP.NET Core 3.1 web app with Yahoo. To do this, I have to set up Authorization with OAuth. I have followed a few different guides, including:
https://developer.yahoo.com/oauth2/guide/openid_connect/getting_started.html
https://www.yogihosting.com/implementing-yahoo-oauth-2-0-in-csharp-and-asp-net/
I have set up my app in Yahoo, with the configuration found in the below picture:
I then have my code set up to send the authorization request to Yahoo with the following code:
public void YahooAuth()
{
string id = configuration["YahooClientId"];
string returnUrl = "https://www.fantasysimmer.com/FootballSimulator/Sim";
string url = $"https://api.login.yahoo.com/oauth2/request_auth?client_id={id}--&response_type=code&redirect_uri={returnUrl}";
Response.Redirect(url);
}
When this code is ran however, I get an error page with a message "Developers: Please specify a valid client and submit again.", and the URL displays:
https://api.login.yahoo.com/oauth2/error?client_id={Client_ID}--&error=unauthorized_client&error_description=invalid+client+id
I double and triple checked the Client ID, and the client ID in the URL is the same as in my Yahoo App's profile. I'm wondering now, is there an extra step that I missed in registering my app, or is there something wrong with my code?
Edit: Progress is made! The dashes after the client id must have been part of the example, or otherwise were an error. When I removed that, I started getting a new error, saying to enter in a valid request. It had something to do with my return url, because replacing that with 'oob' made it go through.
So there were two errors. The first was that the "--" after the client id were not supposed to be there. I'm not sure why in yahoo's example they have them there, but they aren't needed. The second reason is that my return uri was capitalized in my code, but not capitalized in my app settings. Now it works!
I have a intranet application which i'm able to login using username/password.
Im trying to access the same application using python requests passing my username/password but that does not work. Its a difficult task to get a application support.
Meanwhile, I want to see if I can login using the session the web application created which is in my other browser.
How can I just pass the session using the requests module.
You may need to send data among username and password (usually this data is generated randomly by the server and are inside <input type="hidden"> form elements) which we prevent the CSRF (cross-site request forgery) attack. You may also need to send cookies the Web server send to you.
So, to solve your problem you need to:
Create a requests session to handle cookies;
Request the login page (where the form is) and extract CSRF data;
Post CSRF data among your credentials to the form action URL.
The code will be like this:
import requests
LOGIN_URL = '...' # put URL here
# replace 'user' and 'pass' with form field names for credentials
CREDENTIALS = {'user': '...', 'pass': '...'}
session = requests.session()
# get cookies and CSRF data
response = session.get(LOGIN_URL)
csrf_data = ... # extract data from response.text in a dict
# post data
csrf_data.update(CREDENTIALS)
# you may change LOGIN_URL below with form's 'action' URL if they differ
response = session.post(LOGIN_URL, data=csrf_data)
# now check response.text to see if you're logged in
There are many ways to extract CSRF data, such as: simple string manipulation, regular expressions or more specialized libraries such as lxml and BeautifulSoup (it depends on your input HTML and familiarity with the methods).
I am trying to test a scenario where an http request is ran to login to a site using username and password and on success it redirects to google.com.It also creates session cookies of its own which I am able to view in the Firefox browser manually.
However when I am trying to retrieve all cookies using Selenium Webdriver, it is just returning the cookies that belong to the present domain.
I am using the following code:
Set <Cookie> allCookies=driver.manage().getCookies();
Iterator <Cookie> itr=allCookies.iterator();
APPLICATION_LOGS.info("Cookie Size--->"+driver.manage().getCookies().size());
while(itr.hasNext())
{
Cookie c=itr.next();
APPLICATION_LOGS.info("Cookie Domain--->"+c.getDomain()+"Cookie Name---"+c.getName()+"Cookie Value---"+c.getValue());
}
Please let me know if there is any other way to retrieve all the cookies.
I would like to get a list of meetings on the server however when i do a https://example.com/api/xml?action=report-bulk-objects&filter-type=meeting replacing the domain with my connect domain i get an access denied response. I am signed in to the connect work space and I am in the admin group. What could be the cause of this?
response:
<results>
<status code="no-access" subcode="denied"/>
</results>
This should work if you're in the admin group, logged in, and submitting the request from the same browser that's logged in. You might try adding the session parameter to your request ("&session=breez123abc456def")
The value of the parameter must be that of the BREEZESESSION cookie set by the Connect server on your authenticated session. One of several ways to discover that is with the common-info API method: https://connect.example.com/api/xml?action=common-info It'll be in the /results/common/cookie element.
If this still isn't working, check the debug.log on the server(s) for the failing request; there should be additional information there.
I can't get my refresh token with my code. I can only get my access token, token type etc.,
I have followed some tutorials like putting access_type=offline on my login URL:
echo "<a href='https://accounts.google.com/o/oauth2/auth?"
. "access_type=offline&client_id=123345555.apps.googleusercontent.com& "
. "scope=https://www.googleapis.com/auth/calendar+https://www.googleapis.com/auth/plus.me&response_type=code& "
. "redirect_uri=http://www.sample.com/sample.php&state=/profile'>Google</a>";
and my fields in getting the access token:
$fields=array(
'code'=> urlencode($authcode),
'client_id'=> urlencode($clientid),
'client_secret'=> urlencode($clientsecret),
'redirect_uri'=> urlencode($redirecturi),
'grant_type'=> 'authorization_code',
);
but I can't get refresh_token, just the access_token, token_type, id_token and expires_in.
Found out by adding this to your url parameters
approval_prompt=force
Update:
Use access_type=offline&prompt=consent instead.
approval_prompt=force no longer works
https://github.com/googleapis/oauth2client/issues/453
If I may expand on user987361's answer:
From the offline access portion of the OAuth2.0 docs:
When your application receives a refresh token, it is
important to store that refresh token for future use. If your
application loses the refresh token, it will have to re-prompt the
user for consent before obtaining another refresh token. If you need
to re-prompt the user for consent, include the approval_prompt
parameter in the authorization code request, and set the value to
force.
So, when you have already granted access, subsequent requests for a grant_type of authorization_code will not return the refresh_token, even if access_type was set to offline in the query string of the consent page.
As stated in the quote above, in order to obtain a new refresh_token after already receiving one, you will need to send your user back through the prompt, which you can do by setting approval_prompt to force.
Cheers,
PS This change was announced in a blog post as well.
It is access_type=offline that you want.
This will return the refresh token the first time the user authorises the app. Subsequent calls do not force you to re-approve the app (approval_prompt=force).
See further detail:
https://developers.google.com/accounts/docs/OAuth2WebServer#offline
This is complete code in PHP using google official SDK
$client = new Google_Client();
## some need parameter
$client->setApplicationName('your application name');
$client->setClientId('****************');
$client->setClientSecret('************');
$client->setRedirectUri('http://your.website.tld/complete/url2redirect');
$client->setScopes('https://www.googleapis.com/auth/userinfo.email');
## these two lines is important to get refresh token from google api
$client->setAccessType('offline');
$client->setApprovalPrompt('force'); # this line is important when you revoke permission from your app, it will prompt google approval dialogue box forcefully to user to grant offline access
For our app we had to use both these parameters access_type=offline&prompt=consent.
approval_prompt=force did not work for us
Hi I followed following steps and I had been able to get the refresh token.
Authorization flow has two steps.
Is to obtain the authorization code using https://accounts.google.com/o/oauth2/auth? URL.
For that a post request is sent providing following parameters. 'scope=' + SCOPE + '&client_id=' + CLIENTID + '&redirect_uri=' + REDIRECT + '&response_type=' + TYPE + '&access_type=offline' Providing above will receive a authorization code.
Retrieving AcessToken and RefreshToken using https://accounts.google.com/o/oauth2/token? URL.
For that a post request is sent providing following parameters.
"code" : code,
"client_id" : CID,
"client_secret" : CSECRET,
"redirect_uri" : REDIRECT,
"grant_type" : "authorization_code",
So in your first attempt once you authorize the permissions you will be able to get the Refresh token. Subsequent attempts will not provide the refresh token. If you want the token again the revoke the access in you application.
Hope this will help someone cheers :)
OAuth has two scenarios in real mode.
The normal and default style of access is called online.
In some cases, your application may need to access a Google API when the user is not present,It's offline scenarios .
a refresh token is obtained in offline scenarios during the first authorization code exchange.
So you can get refersh_token is some scenarios ,not all.
you can have the content in https://developers.google.com/identity/protocols/OAuth2WebServer#offline
.
Since March 2016, use prompt=consent to regenerate Google API refresh token.
As mentioned in https://github.com/googleapis/oauth2client/issues/453,
approval_prompt=force has been replaced with prompt=none|consent|select_account
For those using the Google API Client Library for PHP and seeking offline access and refresh tokens beware as of the time of this writing the docs are showing incorrect examples.
currently it's showing:
$client = new Google_Client();
$client->setAuthConfig('client_secret.json');
$client->addScope(Google_Service_Drive::DRIVE_METADATA_READONLY);
$client->setRedirectUri('http://' . $_SERVER['HTTP_HOST'] . '/oauth2callback.php');
// offline access will give you both an access and refresh token so that
// your app can refresh the access token without user interaction.
$client->setAccessType('offline');
// Using "consent" ensures that your application always receives a refresh token.
// If you are not using offline access, you can omit this.
$client->setApprovalPrompt("consent");
$client->setIncludeGrantedScopes(true); // incremental auth
source: https://developers.google.com/identity/protocols/OAuth2WebServer#offline
All of this works great - except ONE piece
$client->setApprovalPrompt("consent");
After a bit of reasoning I changed this line to the following and EVERYTHING WORKED
$client->setPrompt("consent");
It makes sense since using the HTTP requests it was changed from approval_prompt=force to prompt=consent. So changing the setter method from setApprovalPrompt to setPrompt follows natural convention - BUT IT'S NOT IN THE DOCS!!! That I found at least.