Koder 228
Koder 228

Reputation: 200

AWS QuickSight rails integration authorization code error

I have a rails application that needs to add QuickSight. Found that for these purposes it is necessary to use the get_dashboard_embed_url method. This method returns me the URL, but following it (manually, through an iframe tag) I get this error text
Embedding failed because of invalid URL or authorization code. Both of these must be valid and the authorization code must not be expired for embedding to work.
Where can I find the authenticate code? How can I get it? Thanks for your help
This is how i fetch the url

credential_options = {
  client: Aws::STS::Client.new(region: ENV['AWS_REGION']),
  role_arn: ENV['QUICK_SIGHT_ROLE_ARN'],
  role_session_name: self.user_email
}

assume_role_credential = Aws::AssumeRoleCredentials.new(credential_options)
qs_client = Aws::QuickSight::Client.new({
  credentials: assume_role_credential,
  region: ENV['AWS_REGION']
})

begin
  qs_client.register_user({
    identity_type: 'IAM', # accepts IAM, QUICKSIGHT
    email: self.user_email,
    user_role: 'READER', # accepts ADMIN, AUTHOR, READER, RESTRICTED_AUTHOR, RESTRICTED_READER
    iam_arn: ENV['QUICK_SIGHT_ROLE_ARN'],
    session_name: self.user,
    aws_account_id: ENV['AWS_ACCOUNT_ID'],
    namespace: 'default'
  })
rescue
end

options = {
  aws_account_id: ENV['AWS_ACCOUNT_ID'],
  dashboard_id: ENV['QUICK_SIGHT_DASHBOARD_ID'],
  identity_type: 'IAM',
  session_lifetime_in_minutes: 300,
  undo_redo_disabled: false,
  reset_disabled: false
}

qs_client.get_dashboard_embed_url(options, {}).embed_url

And how i try to display
iframe src=@url class='w-100 h-100' style='min-height: 500px;'

Upvotes: 2

Views: 3508

Answers (1)

Koder 228
Koder 228

Reputation: 200

At the first, sorry for my weak english, but i hope that you'll understand what i mean
Ok, after completing these points, everything began to work for me. Also read "Underwater rocks", this is very important points list which will save you tons of time

  • Replace my code in question with this

    def fetch_url # this method fetch embed dashboard url
       credential_options = {
         client: Aws::STS::Client.new(
           region: ENV['AWS_REGION'],
           access_key_id: ENV['AWS_ACCESS_KEY_ID'],
           secret_access_key: ENV['AWS_SECRET_ACCESS_KEY']
         ),
         role_arn: ENV['QUICK_SIGHT_ROLE_ARN'],
         role_session_name: self.user_email # This is attr_accessor :user_email
       }
    
       assume_role_credential = Aws::AssumeRoleCredentials.new(credential_options)
       qs_client = Aws::QuickSight::Client.new({
         credentials: assume_role_credential,
         region: ENV['AWS_REGION']
       })
    
       begin
         qs_client.register_user({
           identity_type: 'IAM', # accepts IAM, QUICKSIGHT
           email: self.user_email,
           user_role: 'READER', # accepts ADMIN, AUTHOR, READER, RESTRICTED_AUTHOR, RESTRICTED_READER
           iam_arn: ENV['QUICK_SIGHT_ROLE_ARN'],
           session_name: self.user_email,
           aws_account_id: 'ENV['AWS_ACCOUNT_ID']',
           namespace: 'default'
         })
       rescue
       end
    
       options = {
         aws_account_id: ENV['AWS_ACCOUNT_ID'],
         dashboard_id: ENV['QUICK_SIGHT_DASHBOARD_ID'],
         identity_type: 'IAM',
         session_lifetime_in_minutes: 300,
         undo_redo_disabled: false,
         reset_disabled: false
       }
    
       qs_client.get_dashboard_embed_url(options).embed_url
     end
    
  • Go to Manage QuickSight panel https://your-quicksight-region(us-east-2 for example).quicksight.aws.amazon.com/sn/admin#users and click on "Manage permissions" button (button is placed above of the table with users)

  • On the new page click on "Create" button and select "Sharing dashboards" checkbox. Set the name of the permission, click on the "Create" button

  • In your controller action: @url = fetch_url # fetch_url - method from 1 point

  • Add to your view: iframe src=@url OR you can use a amazon-quicksight-embedding-sdk but for me the iframe works pretty well

Underwater rocks

  • Remember that dashboard url (which you are get with this method qs_client.get_dashboard_embed_url(options).embed_url) can be used only once, i.e. you can't open two browsers tabs with the same URL. When you are will pass this URL to iframe, this URL will cease to be working and you will no longer be able to use it in others browser windows or others iframe's

  • Add your app domain to whitelist domains on the QuickSight. You can do it in the Manage QuickSight panel https://your-quicksight-region.quicksight.aws.amazon.com/sn/admin#embedding

  • !!!IMPORTANT!!! if you are trying to embed dashboard to your localhost:your_server_port_number rails server, then you will always get the error message into the iframe (but if you go to this URL through the address bar of the browser, then you should see your dashboard (comment out / remove the iframe so it doesn't use the link, because every embedded dashboard url is disposable)). This is because localhost:your_server_port_number is not provided in the whitelist (Underwater rocks p.2). For resolving this issue and testing your work you can use ngrok (maybe it's available only for macOS, i'm not sure).
    When you'll download the ngrok open your terminal and run command
    $ ./path_to_ngrok_script/./ngrok http your_server_port_number
    For me it's:
    $ ~/./scripts/ngrok http 3000

    After that do these 3 things for adding your work station to QuickSight whitelist:

  • In the terminal with ngrok copy generated domain which starts with the https (i'll name it ngrok_domain), NOT WITH HTTP. For example: https://047956358355.ngrok.io

  • Go to the Underwater rocks p.2 and add ngrok_domain

  • Open your browser and go to the path with iframe, but use ngrok_domain instead of localhost:3000. For example, your embedded dashboard path is localhost:3000/embed_dashboard. Change it to https://047956358355.ngrok.io/embed_dashboard



After all these steps all is start working for me. I'm sure that some of the points here are superfluous, but i'm really tired of working with this integration, so here you yourself decide what should be left and what should be removed.
I hope my answer helped at least someone

Upvotes: 1

Related Questions