I'm trying to get a html button to redirect to my Azure login page from the homepage.
If I put in my browser localhost/3000/authentication/login it goes to the Azure web app.
This is what I'm trying to achieve with this:
<%= button_to 'Login', authentication_login_path, method: :get %>
My routes file is:
Rails.application.routes.draw do
root 'application#home'
get 'application/home'
get 'authentication/login', to: 'authentication#index'
resources :authentication
end
The Application and Home controllers just have blank functions at the moment.
I've tried rake | grep authentication and it contains the correct path:
authentication_login GET /authentication/login(.:format) authentication#index
Therefore, I'm not sure what doing authentication_login_path is not recognized in my home.html.erg file.
This is the Authentication_Controller. I'm trying to execute the index method as this will begin the authentication process.
require 'oauth2'
class AuthenticationController < ApplicationController
# You need to configure a tenant at Azure Active Directory(AAD) to register web app and web service app
# You will need two entries for these app at the AAD portal
# You will put clientid and clientsecret for your web app here
# ResourceId is the webservice that you registered
# RedirectUri is registered for your web app
CLIENT_ID = '56938f79-a23e-4f3f-a033-d23546d9056f'
CLIENT_SECRET = '5j8Hv8U1x_l-t047OZq9~LmK~kMdobV3rm'
AUTHORITY = 'https://login.windows.net/'
AUTHORIZE_URL = "https://beautytruth.b2clogin.com/beautytruth.onmicrosoft.com/B2C_1_btSignInSignOut/oauth2/v2.0/authorize"
TOKEN_URL = "https://beautytruth.b2clogin.com/beautytruth.onmicrosoft.com/B2C_1_btSignInSignOut/oauth2/v2.0/token"
RESOURCE_ID = '/subscriptions/eb589fa5-ed57-4e10-81c9-32e4284af10c/resourceGroups/btAdvertisingNetwork' #ResourceId or ResourceURI that you registered at Azure Active Directory
REDIRECT_URI = 'http://localhost:3000/welcome/callback'
def index
update_token
if session['access_token']
puts "Auth has been checked"
# show main page and use token
redirect_to
else
# start authorization
client = get_client
a = client.auth_code.authorize_url(:client_id => CLIENT_ID, :resource => RESOURCE_ID, :redirect_uri => REDIRECT_URI)
redirect_to(a)
end
end
def callback
begin
#code = params[:code]
client = get_client
# post token to mobile service api
#token = client.auth_code.get_token(CGI.escape(#code), :redirect_uri => REDIRECT_URI)
# id_token token.params["id_token"]
#multi resource token token.params["resource"]
token = client.auth_code.get_token(#code, :redirect_uri => REDIRECT_URI, )
session['access_token'] = token.token
session['refresh_token'] = token.refresh_token
session['expire_at'] = token.expire_at
session['instance_url'] = token.params['instance_url']
redirect '/'
rescue => exception
output = '<html><body><p>'
output += "Exception: #{exception.message}<br/>"+exception.backtrace.join('<br/>')
output += '</p></body></html>'
end
end
def update_token
puts "update token inside"
token = session['access_token']
refresh_token = session['refresh_token']
expire_at = session['expire_at']
#access_token = OAuth2::AccessToken.from_hash(get_client, { :access_token => token, :refresh_token => refresh_token, :expire_at => expire_at, :header_format => 'Bearer %s' } )
if #access_token.expired?
puts "refresh token"
#access_token = #access_token.refresh!
session['access_token'] = #access_token.token
session['refresh_token'] = #access_token.refresh_token
session['expire_at'] = #access_token.expire_at
session['instance_url'] = #access_token.params['instance_url']
end
end
# send post request to webservice to send token and create a post request
def use_token
# we got the token and now it will posted to the web service in the header
# you can specify additional headers as well
# token is included by default
update_token
conn = Faraday.new(:url => 'https://btadvertisingplatform.azurewebsites.net/') do |faraday|
faraday.request :url_encoded # form-encode POST params
faraday.response :logger # log requests to STDOUT
faraday.adapter Faraday.default_adapter # make requests with Net::HTTP
end
response = conn.get do |req|
req.url '/api/WorkItem'
req.headers['Content-Type'] = 'application/json'
req.headers['Authorization'] = 'Bearer '+#access_token.token
end
#out = response.body
end
def get_client
client = OAuth2::Client.new(CLIENT_ID, CLIENT_SECRET, :site => AUTHORITY, :authorize_url => AUTHORIZE_URL, :token_url => TOKEN_URL )
client
end
end
As you already have resource :authentication you can use the following.
<%= button_to 'Login', authentication_index_path, method: :get %>
You don't need an additional route. You can remove the following route
get 'authentication/login', to: 'authentication#index'
Related
I spent hours looking for a solution to my problem without luck.
I created a Rails app that interacts with Google Calendar API and, following a guide, I was able to make it work. Then I shut down my local server and ran it again after 2/3 hours and I started receiving this error when I make a request to the API:
Signet::AuthorizationError (Unexpected error: #<ArgumentError: Missing authorization code.>)
I figured out that the problem is that the token is expired, 'cause I can't understand why it was working and then not anymore.
This is my controller:
require 'google/api_client/client_secrets.rb'
require 'google/apis/calendar_v3'
CALENDAR_ID = Here I have my Calendar_ID
GOOGLE_CLIENT_ID = Here I have my Google_Client_ID
GOOGLE_CLIENT_SECRET = Here I have my Google_Client_Secret
class CalendarController < ApplicationController
def calendars
client = Signet::OAuth2::Client.new(client_options)
client.update!(session[:authorization])
service = Google::Apis::CalendarV3::CalendarService.new
service.authorization = client
#calendar_list = service.list_calendar_lists
rescue Google::Apis::AuthorizationError
response = client.refresh!
session[:authorization] = session[:authorization].merge(response)
retry
end
def redirect
client = Signet::OAuth2::Client.new(client_options)
redirect_to client.authorization_uri.to_s, allow_other_host: true
end
def callback
client = Signet::OAuth2::Client.new(client_options)
client.code = params[:code]
response = client.fetch_access_token!
session[:authorization] = response
redirect_to calendars_url
end
private
def client_options
{
client_id: GOOGLE_CLIENT_ID,
client_secret: GOOGLE_CLIENT_SECRET,
authorization_uri: 'https://accounts.google.com/o/oauth2/auth',
token_credential_uri: 'https://accounts.google.com/o/oauth2/token',
scope: Google::Apis::CalendarV3::AUTH_CALENDAR,
redirect_uri: callback_url
}
end
end
Then my routes:
get '/redirect', to: 'calendar#redirect', as: 'redirect'
get '/callback', to: 'calendar#callback', as: 'callback'
get '/calendars', to: 'calendar#calendars', as: 'calendars'
What can I do to solve my issue? I'm a newbie on Rails, so it's not quite simple for me
I am trying to authenticate with QuickBooks Online via OAuth. After clicking authorize on QuickBooks' notification screen, it redirects to the callback url as expected but I do not have access to the request token object I created at the beginning.
I tried using a session variable but the variable is nil when called by QuickBooks. How can I do this?
class QuickBooksController < ApplicationController
def connect
#call_back_url = 'http://127.0.0.1:3000/quickbooks/callback'
#consumer = OAuth::Consumer.new('key', 'secret', {
:site => 'https://oauth.intuit.com',
:request_token_path => '/oauth/v1/get_request_token',
:authorize_url => 'https://appcenter.intuit.com/Connect/Begin',
:access_token_path => '/oauth/v1/get_access_token'
})
#request_token = #consumer.get_request_token(:oauth_callback => #callback_url)
session[:request_token] = #request_token
redirect_to #request_token.authorize_url(:oauth_callback => #call_back_url)
end
def callback
#This does not work because session[:request_token] is nil
#access_token = session[:request_token].get_access_token(:oauth_verifier => params[:oauth_verifier])
end
end
Is there any reference available to connect to Facebook using Oauth2 gem in Rails 4?
I am getting above error while calling get_token method of Oauth2.
def login_facebook
redirect_to client.auth_code.authorize_url(
:redirect_uri => 'http://localhost:3000/oauth/facebook_callback'
)
end
def facebook_callback
token = client.auth_code.get_token(
params[:code],
:token_url => "/oauth/token",
#:token_url => "/oauth/access_token",
# :parse => :query,
:redirect_uri => 'http://localhost:3000/oauth/facebook_callback'
)
puts "**************"
puts token.inspect
puts "**************"
end
private
def client
OAuth2::Client.new(APPLICATION_ID, APPLICATION_SECRET, :site => FB_GRAPH_URL)
end
The default url for requesting the access token has been changed from /oauth/access (which is what FB uses) to /oauth/access_token. Now, you need to override this setting as:
OAuth2::Client.new(FACEBOOK_APP_ID, FACEBOOK_APP_SECRET, {
:token_url => '/oauth/access_token',
:redirect_uri => 'http://localhost:3000/oauth/facebook_callback'
})
You may want to use Koala gem for easy communication with facebook.
I am developing a Rails 4 web application and i am planning to authenticate a user from my Windows Azure AD.
For that i have subscribed to Windows Azure and created Active Directory. I then created an application inside AD to get Client and Secret ID to access API exposed by windows Azure from my Rails web application.
For this i am planning to use Devise gem . Is this the right solution or is there any other libraries available to achieve this.
Any help is appreciated.
Not sure if you're still looking for anything, but this Gist has the requisite request code using the OAuth2 gem. If you were ultimately able to get things working with another means (Devise, etc.), I'd also be interested to know what you did.
Here's the code from the Gist as packaged into a controller by omercs:
require 'oauth2'
class WelcomeController < ApplicationController
# You need to configure a tenant at Azure Active Directory(AAD) to register web app and web service app
# You will need two entries for these app at the AAD portal
# You will put clientid and clientsecret for your web app here
# ResourceId is the webservice that you registered
# RedirectUri is registered for your web app
CLIENT_ID = 'b6a42...'
CLIENT_SECRET = 'TSbx..'
AUTHORITY = 'https://login.windows.net/'
AUTHORIZE_URL = "/yourtenant.onmicrosoft.com/oauth2/authorize"
TOKEN_URL = "/yourtenant.onmicrosoft.com/oauth2/token"
RESOURCE_ID = 'https://yourtenant.onmicrosoft.com/AllHandsTry' #ResourceId or ResourceURI that you registered at Azure Active Directory
REDIRECT_URI = 'http://localhost:3000/welcome/callback'
def index
update_token
if session['access_token']
# show main page and use token
redirect_to welcome_use_token_path
else
# start authorization
client = get_client
a = client.auth_code.authorize_url(:client_id => CLIENT_ID, :resource => RESOURCE_ID, :redirect_uri => REDIRECT_URI)
redirect_to(a)
end
end
def callback
begin
#code = params[:code]
client = get_client
# post token to mobile service api
#token = client.auth_code.get_token(CGI.escape(#code), :redirect_uri => REDIRECT_URI)
# id_token token.params["id_token"]
#multi resource token token.params["resource"]
token = client.auth_code.get_token(#code, :redirect_uri => REDIRECT_URI, )
session['access_token'] = token.token
session['refresh_token'] = token.refresh_token
session['expire_at'] = token.expire_at
session['instance_url'] = token.params['instance_url']
redirect '/'
rescue => exception
output = '<html><body><p>'
output += "Exception: #{exception.message}<br/>"+exception.backtrace.join('<br/>')
output += '</p></body></html>'
end
end
def update_token
puts "update token inside"
token = session['access_token']
refresh_token = session['refresh_token']
expire_at = session['expire_at']
#access_token = OAuth2::AccessToken.from_hash(get_client, { :access_token => token, :refresh_token => refresh_token, :expire_at => expire_at, :header_format => 'Bearer %s' } )
if #access_token.expired?
puts "refresh token"
#access_token = #access_token.refresh!;
session['access_token'] = #access_token.token
session['refresh_token'] = #access_token.refresh_token
session['expire_at'] = #access_token.expire_at
session['instance_url'] = #access_token.params['instance_url']
end
end
# send post request to webservice to send token and create a post request
def use_token
# we got the token and now it will posted to the web service in the header
# you can specify additional headers as well
# token is included by default
update_token
conn = Faraday.new(:url => 'https://yoursite.azurewebsites.net/') do |faraday|
faraday.request :url_encoded # form-encode POST params
faraday.response :logger # log requests to STDOUT
faraday.adapter Faraday.default_adapter # make requests with Net::HTTP
end
response = conn.get do |req|
req.url '/api/WorkItem'
req.headers['Content-Type'] = 'application/json'
req.headers['Authorization'] = 'Bearer '+#access_token.token
end
#out = response.body
end
def get_client
client = OAuth2::Client.new(CLIENT_ID, CLIENT_SECRET, :site => AUTHORITY, :authorize_url => AUTHORIZE_URL, :token_url => TOKEN_URL )
client
end
end
So I logged in with Google and it hits my callback url with a code parameter.
Here is how I initiate my client, I'm using oauth2 gem.
def oauth_client(channel_name)
file = YAML.load_file("#{Rails.root}/config/oauth_credentials.yml")
client_id = file['oauth_credentials'][channel_name]['client_id']
client_secret = file['oauth_credentials'][channel_name]['secret']
site = file['oauth_credentials'][channel_name]['site']
OAuth2::Client.new(client_id, client_secret, site: site, authorize_url: "/o/oauth2/auth", connection_opts: { params: { scope: "https://www.googleapis.com/auth/adsense https://www.googleapis.com/auth/analytics.readonly" } })
end
def oauth_url_for(channel_name)
client = oauth_client(channel_name)
client.auth_code.authorize_url(:redirect_uri => oauth_callback_url(channel: channel_name))
end
Here's my controller
class Oauth2Controller < ApplicationController
include ApplicationHelper
def callback
token = oauth_client(params[:channel]).auth_code.get_token(params[:code], :redirect_uri => oauth_callback_url(channel: params[:channel]))
current_user.connections.create!(channel: params[:channel], token: token)
render text: request.inspect
end
end
Unfortunately I can't get_token due to a response from google saying The page you requested is invalid.
It doesn't look like you're defining the token_url value in your initialization of the client, or later. It is "o/oauth2/token". By default "/oauth/token" is used, so that's likely the cause of your "page you requested is invalid" error.
Source:
http://rubydoc.info/gems/oauth2/0.8.0/OAuth2/Client#initialize-instance_method