How to start the oauth2 token retrieval at the beginning of the script, automatically without clicking on the "Get Token"?
I have found the groovy script to launch the oauth2 get token:
import com.eviware.soapui.impl.rest.actions.oauth.OltuOAuth2ClientFacade
def authContainer = testRunner.testCase.testSuite.project.OAuth2ProfileContainer
// Get OAuth2 profile name
def profileName = context.expand("Oauth2")
def authProfile = authContainer.getProfileByName(profileName)
def clientFacade = new OltuOAuth2ClientFacade()
clientFacade.requestAccessToken(authProfile)
//To get the access token
def accessToken = authProfile.getAccessToken()
Related
I am trying to develop a simple tool that uses Authlib OAuth2 server to get refresh tokens but example server here does not issue a refresh token. When I print the token I get the following:
{'access_token': '....', 'scope': 'profile', 'token_type': 'Bearer', 'expires_in': 864000, 'expires_at': 1532191887}
The flow is Authorization code as referred here; first I handle the consent part:
client_id = '...'
client_secret = '.....'
scope = '...'
session = OAuth2Session(client_id, client_secret, scope=scope)
authorize_url = '.../oauth/authorize'
uri, state = session.authorization_url(authorize_url)
Then I try to get the token:
urlset = '.../?code=...&state=...'
access_token_url = '.../oauth/token'
token = session.fetch_access_token(access_token_url,authorization_response=urlset)
Add a config of OAUTH2_REFRESH_TOKEN_GENERATOR=True, added in commit:
https://github.com/authlib/example-oauth2-server/commit/4f2f48cc3e74b631d9c4c3bdf8558da3de7365a2
See documentation: https://docs.authlib.org/en/latest/flask/2/
I'm trying to implement a Grails app that provides OAuth2 using the Spring Security OAuth2 Provider plugin. The provider app and a client app that I use to test it, are both available on GitHub.
I've followed the instructions in the plugin's docs, that explain how to implement a provider. To test it, I saved the following oauth client and user in Bootstrap.groovy
def init = { servletContext ->
def saveArgs = [flush: true, failOnError: true]
def userRole = new Role(authority: 'ROLE_USER').save(saveArgs)
def clientRole = new Role(authority: 'ROLE_CLIENT').save(saveArgs)
// create an OAuth client
new Client(
clientId: 'my-client',
authorizedGrantTypes: ['authorization_code', 'refresh_token', 'implicit', 'password', 'client_credentials'],
authorities: ['ROLE_CLIENT'],
scopes: ['read', 'write'],
redirectUris: ['http://localhost:9090/oauth-client/auth/callback']
).save(saveArgs)
// create a regular user
def user = new User(username: 'me', password: 'password').save(saveArgs)
UserRole.create user, userRole, true
}
In the client app, I click on the following link that initiates the authorization code grant flow
<g:set var="redirectUrl" value="${g.createLink(controller: 'auth', action: 'callback', absolute: true)}"/>
<h2>
OAuth Login
</h2>
I enter the username and password of the above user in the login form, then click the "Authorize" button shown in the confirmation dialog thereafter. An authorization code is successfully returned to the client app, but when it tries to exchange this for an access token the following error occurs
invalid_scope: Empty scope (either the client or the user is not allowed the requested scopes)
The code used to exchange the authorization code for an access token is shown below.
String getAccessToken(String authCode) {
def url = 'http://localhost:8080/oauth2-provider/oauth/token'
def params = [
grant_type: 'authorization_code',
code: authCode,
client_id: 'my-client'
]
new HTTPBuilder(url).request(POST, JSON) {
uri.query = params
response.success = { resp, json ->
json.access_token
}
response.failure = { resp, json ->
log.error "HTTP error code: $resp.status, status line: $resp.statusLine, "
json.each { key, value ->
log.error "$key: $value"
}
}
}
}
The link that initiates the OAuth process requests access to the read scope. This is included in the scopes property of the Client object, so there's no obvious reason why access to this scope should be prohibited.
You can reproduce the error by following these instructions:
Start the provider app with grails run-app
Start the client app on port 9090 with grails run-app -Dserver.port=9090
On the homepage of the client app click the "OAuth Login" link. This redirects to the provider app and prompts you to login. Enter the username "me", password "password", and click the "Authorize" button in the confirmation dialog that follows.
For anyone who stumbles across this in the future:
This was the result of a small bug in the plugin. The temporary workaround is to include the scope parameter in the token endpoint request with the same value as the scope parameter sent to the authorization endpoint.
See issue #64 on the plugin's GitHub repository for more details about the problem.
I'm trying to get user information from Withings Api, i've already success login into Withings with Oauth using Scribe library(Java). But there is a problem when i sent request to get user information follow Withings Api document it always return result with error code.
I've tried some way but it didn't work. Can someone help me to solve this problem.
Withings Api http://www.withings.com/en/api#documentation
First i call withings action in WithingsController.groovy to get authentication.
After authenticate success server return access token, in withingsCallback action i get user information.
Result return when get user information is result code of Withings Api
{"status":2554}
This is my code
WithingsService.groovy
def getAuthDetails(callbackUrl) {
if (!authService) {
authService = new ServiceBuilder()
.provider(WithingsApi.class)
.apiKey( grailsApplication.config.oauth.withings.key as String )
.apiSecret( grailsApplication.config.oauth.withings.secret as String )
.callback( callbackUrl as String )
.build();
}
Token requestToken = authService.getRequestToken();
[ authUrl : authService.getAuthorizationUrl(requestToken), requestToken : requestToken ]
}
def getWithingsUserInformation(Token accessToken,String userId){
String url = 'http://wbsapi.withings.net/user?action=getbyuserid&userid='+userId;
OAuthRequest request = new OAuthRequest( Verb.POST, url )
authService.signRequest(accessToken, request)
Response response = request.send()
return response
}
def getAccessToken( params, requestToken ){
requestToken = requestToken as Token
Verifier verifier = new Verifier( params.oauth_verifier )
authService.getAccessToken(requestToken, verifier);
}
WithingsController.groovy
def withings() {
def authInfo = withingsService.getAuthDetails(createLink(action: 'withingsCallback', controller: 'withings', absolute: 'true'))
if (authInfo.requestToken)
{
session["withings_requestToken"] = authInfo.requestToken
}
}
def withingsCallback(){
def accessToken = withingsService.getAccessToken(params, session["withings_requestToken"])
session["withings_accessToken"] = accessToken
if(accessToken) {
def profile
String userId = params.userid
profile = withingsService.getWithingsUserInformation(accessToken,userId)
}
}
Unless I'm missing something, it looks like you are not redirecting your user to get the "access token". After you get a request token:
you then generate a authentication url
redirect the user to this authentication url
they will authenticate
if authentication is successful, provider will call your callback with access token
So your withings action should include:
def withings() {
def authInfo = withingsService.getAuthDetails(createLink(action: ....
if (authInfo.requestToken)
{
session["withings_requestToken"] = authInfo.requestToken
}
//are you missing this?
redirect(authInfo.authUrl)
}
If you're using some type of http debugging/logging, check for the following request after your withings action.
https://oauth.withings.com/account/authorize?
oauth_callback=http%3A%2F%2Fexample.com%2Fget_access_token
&oauth_consumer_key=c331c571585e7c518c78656f41582e96fc1c2b926cf77648223dd76424b52b
&oauth_nonce=369f9ceb2f285ac637c9a7e9e98019bd
&oauth_signature=OR9J9iEl%2F2yGOXP2wk5c2%2BWtYvU%3D
&oauth_signature_method=HMAC-SHA1
&oauth_timestamp=1311778988
&oauth_token=5bb105d2292ff43ec9c0f633fee9033045ed4643e9871b80ce586dc1bf945
&oauth_version=1.0
Though this is unrelated to the question initially asked, I thought I would post here since this was a common stopping ground for me reaching a Withings 2554 error.
If updating to the newest version of Withings Api for access token authentication, the current version of the Withings Api will now also cause this 2554 status code if you do not attach action: requesttoken to the access token request body.
Additionally, when pulling apart the response, make sure to drill into the body of the payload, since the latest version of the Withings access token api delivers its payload contents differently. This may be a no brainer for those implementing from scratch, but if you are using an oauth library, most of this behavior is abstracted by the library, and it likely won't be anticipating the payload structure to contain the body field.
more info here: https://developer.withings.com/api-reference#operation/oauth2-getaccesstoken
I am trying my hand ruby on rails. Mostly I have written code in Sinatra. Anyway this question may not have to do anything with framework. And this question may sound a very novice question. I am playing with Twitter 1.1 APIs and OAuth first time.
I have created an app XYZ and registered it with Twitter. I got XYZ's consumer key i.e., CONSUMER_KEY and consumer secret i.e. CONSUMER_SECRET. I also got XYZ's own access token i.e ACCESS_TOKEN and access secret i.e. ACCESS_SECRET
XYZ application type: Read, Write and Access direct messages
XYZ callback URL: http://www.mysite.com/cback
And I have checked: Allow this application to be used to Sign in with Twitter
What I am trying to do is very simple:
1) Users come to my website and click a link Link your twitter account (not signin with twitter)
2) That opens twitter popup where user grants permission to XYZ to perform actions on his/her behalf
3) Once user permits and popup gets closed, XYZ app gets user's access token and secret and save in the database.
4) Then XYZ uses that user's token and secret to perform actions in future.
I may be moron that such work flow has been implemented on several thousands sites and Twitter API documentations explain this 3-legged authentication, still I am unable to figure it out.
I have read https://dev.twitter.com/docs/auth/3-legged-authorization and https://dev.twitter.com/docs/auth/implementing-sign-twitter Unfortunately no ruby code found on internet that explains with step by step example.
What link should be used to open twitter authentication page when user clicks Link your twitter account.
Can anyone here, write some pseudo code with my pseduo credential above to achieve my goal from beging till end of this work flow? Thanks.
UPDATE:
I started with requesting request token as
require 'oauth'
consumer = OAuth::Consumer.new(CONSUMER_KEY, CONSUMER_SECRET,
{ site: "https://twitter.com"})
request_token = consumer.get_request_token oauth_callback: 'http://www.mysite.com/tauth'
redirect_to request_token.authorize_url
I'm not familiar with ROR but here is the workflow of the OAuth 'dance' that you need to follow when the user clicks your button:
Obtain an unauthorized request token from Twitter by sending a
request to
POST https://api.twitter.com/oauth/request_token
signing the request using your consumer secret. This will be done in the background and
will be transparent to the user.
You will receive am oauth_token and oauth_token_secret back from
twitter.
Redirect the user to
https://api.twitter.com/oauth/authorize?oauth_token=[token_received_from_twitter]
using the oauth token value you received from Twitter in step 2.
When the user authorizes your app they will be redirected to your
callback url with oauth_token and oauth_verifier appended to the
url. i.e.
http://www.mysite.com/cback?oauth_token=NPcudxy0yU5T3tBzho7iCotZ3cnetKwcTIRlX0iwRl0&oauth_verifer=uw7NjWHT6OJ1MpJOXsHfNxoAhPKpgI8BlYDhxEjIBY
Convert the request token into an access token by sending a signed
request along with the oauth_verifier to
POST
https://api.twitter.com/oauth/access_token
signing your request
with your consumer secret and the token secret received in step 2.
If everything goes ok, you will receive a new oauth_token and
oauth_token_secret from Twitter. This is your access token for the
user.
Using the access token and secret received in step 6 you can make
Twitter api calls on behalf the the user by sending signed requests
to the appropriate api endpoints.
Hope you solved your problem by this time, but I built this sample Sign in with Twitter ruby web app that provide all explanation you need to do this integration. Below there's a class that implements all necessary methods with comments:
require "net/https"
require "simple_oauth"
# This class implements the requests that should
# be done to Twitter to be able to authenticate
# users with Twitter credentials
class TwitterSignIn
class << self
def configure
#oauth = YAML.load_file(TWITTER)
end
# See https://dev.twitter.com/docs/auth/implementing-sign-twitter (Step 1)
def request_token
# The request to get request tokens should only
# use consumer key and consumer secret, no token
# is necessary
response = TwitterSignIn.request(
:post,
"https://api.twitter.com/oauth/request_token",
{},
#oauth
)
obj = {}
vars = response.body.split("&").each do |v|
obj[v.split("=").first] = v.split("=").last
end
# oauth_token and oauth_token_secret should
# be stored in a database and will be used
# to retrieve user access tokens in next requests
db = Daybreak::DB.new DATABASE
db.lock { db[obj["oauth_token"]] = obj }
db.close
return obj["oauth_token"]
end
# See https://dev.twitter.com/docs/auth/implementing-sign-twitter (Step 2)
def authenticate_url(query)
# The redirection need to be done with oauth_token
# obtained in request_token request
"https://api.twitter.com/oauth/authenticate?oauth_token=" + query
end
# See https://dev.twitter.com/docs/auth/implementing-sign-twitter (Step 3)
def access_token(oauth_token, oauth_verifier)
# To request access token, you need to retrieve
# oauth_token and oauth_token_secret stored in
# database
db = Daybreak::DB.new DATABASE
if dbtoken = db[oauth_token]
# now the oauth signature variables should be
# your app consumer keys and secrets and also
# token key and token secret obtained in request_token
oauth = #oauth.dup
oauth[:token] = oauth_token
oauth[:token_secret] = dbtoken["oauth_token_secret"]
# oauth_verifier got in callback must
# to be passed as body param
response = TwitterSignIn.request(
:post,
"https://api.twitter.com/oauth/access_token",
{:oauth_verifier => oauth_verifier},
oauth
)
obj = {}
vars = response.body.split("&").each do |v|
obj[v.split("=").first] = v.split("=").last
end
# now the we got the access tokens, store it safely
# in database, you're going to use it later to
# access Twitter API in behalf of logged user
dbtoken["access_token"] = obj["oauth_token"]
dbtoken["access_token_secret"] = obj["oauth_token_secret"]
db.lock { db[oauth_token] = dbtoken }
else
oauth_token = nil
end
db.close
return oauth_token
end
# This is a sample Twitter API request to
# make usage of user Access Token
# See https://dev.twitter.com/docs/api/1.1/get/account/verify_credentials
def verify_credentials(oauth_token)
db = Daybreak::DB.new DATABASE
if dbtoken = db[oauth_token]
# see that now we use the app consumer variables
# plus user access token variables to sign the request
oauth = #oauth.dup
oauth[:token] = dbtoken["access_token"]
oauth[:token_secret] = dbtoken["access_token_secret"]
response = TwitterSignIn.request(
:get,
"https://api.twitter.com/1.1/account/verify_credentials.json",
{},
oauth
)
user = JSON.parse(response.body)
# Just saving user info to database
user.merge! dbtoken
db.lock { db[user["screen_name"]] = user }
result = user
else
result = nil
end
db.close
return result
end
# Generic request method used by methods above
def request(method, uri, params, oauth)
uri = URI.parse(uri.to_s)
# always use SSL, you are dealing with other users data
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
# uncomment line below for debug purposes
#http.set_debug_output($stdout)
req = (method == :post ? Net::HTTP::Post : Net::HTTP::Get).new(uri.request_uri)
req.body = params.to_a.map { |x| "#{x[0]}=#{x[1]}" }.join("&")
req["Host"] = "api.twitter.com"
# Oauth magic is done by simple_oauth gem.
# This gem is enable you to use any HTTP lib
# you want to connect in OAuth enabled APIs.
# It only creates the Authorization header value for you
# and you can assign it wherever you want
# See https://github.com/laserlemon/simple_oauth
req["Authorization"] = SimpleOAuth::Header.new(method, uri.to_s, params, oauth)
http.request(req)
end
end
end
More detailed explanation at:
https://github.com/lfcipriani/sign_in_with_twitter_sample
I'm trying to implement "twitter oauth" in appengine(python) using http://code.google.com/p/oauth-python-twitter.
I use the following code to redirect the user into twitter:
twitter = OAuthApi(CONSUMER_KEY, CONSUMER_SECRET)
request_token = twitter.getRequestToken()
response.set_cookie('request_token', request_token.to_string())
signin_url = twitter.getAuthorizationURL(request_token)
return redirect_to(signin_url)
the user is successfully redirected but when he returns in my application i receive the following error:
HTTP Error 401: Unauthorized
File "/base/data/home/apps/app/controllers/users.py", line 46, in authenticate
access_token = twitter.getAccessToken()
File "/base/data/home/apps/app/lib/python/oauthtwitter.py", line 183, in getAccessToken
token = self._FetchUrl(url, no_cache=True)
......
File "/base/python_dist/lib/python2.5/urllib2.py", line 506, in http_error_default
raise HTTPError(req.get_full_url(), code, msg, hdrs, fp)
the error occurate when i try to get an access token.
request_token = request.cookies['request_token']
token = oauth.OAuthToken.from_string(request_token)
twitter = OAuthApi(app_globals.CONSUMER_KEY, app_globals.CONSUMER_SECRET, token) # everything works good
access_token = twitter.getAccessToken() # then, i receive the error.
Any idea?
Thank you!
i solved the problem just using the trunk version of oauth-python-twitter and python-twitter.
Make sure the user (or your self) has entered your app name in the Twitter authenticated section of their/your Twitter account so that your application has permission to connect.