Unable to Embed Power BI Report - java

In Azure portal I have registered an App of type 'Native'. In Java I was able to get the access token using this API call
POST https://login.windows.net/common/oauth2/token
Request Params
client_id: appId on azure portal
grant_type: "password" this is hardcorded
resource: "https://analysis.windows.net/powerbi/api"
username: email
password: password of the email
This gives me an accessToken and a refreshToken. I can use this accessToken to call any of the Power BI API. Like get all reports, clone reports, create datasets etc.
Now I want to embed a report to my web page and I use this API using jquery
function embedPBIReport(txtAccessToken, embedUrl, embedReportId, mode) {
// Read embed URL from textbox
var txtEmbedUrl = embedUrl;
// Read report Id from textbox
var txtEmbedReportId = embedReportId;
// Get models. models contains enums that can be used.
var models = window['powerbi-client'].models;
// We give All permissions to demonstrate switching between View and Edit mode and saving report.
var permissions = mode == 1 ? models.Permissions.Read : models.Permissions.ReadWrite ;
var viewMode = mode == 1 ? models.ViewMode.View : models.ViewMode.Edit;
// Embed configuration used to describe the what and how to embed.
// This object is used when calling powerbi.embed.
// This also includes settings and options such as filters.
// You can find more information at https://github.com/Microsoft/PowerBI-JavaScript/wiki/Embed-Configuration-Details.
var config = {
type: 'report',
tokenType: models.TokenType.Embed,
accessToken: txtAccessToken,
embedUrl: txtEmbedUrl,
id: txtEmbedReportId,
permissions: permissions,
viewMode: viewMode,
settings: {
filterPaneEnabled: false,
navContentPaneEnabled: true
}
};
// Get a reference to the embedded report HTML element
var embedContainer = $('#reportContainer');
// Embed the report and display it within the div container. --> -->
var report = embedContainer.powerbi(config);
}
When I initiate embed on web page, it creates an Iframe and shows Power BI icon as loader and then throws this error
{"message":"LoadReportFailed","detailedMessage":"Get report failed","errorCode":"403","level":6,"technicalDetails":{"requestId":"f62b4819-7cd0-1c6d-1af0-a89050881a8a"}}
I have googled this issue and people are saying 403 is caused when authentication process is not correct. What am I doing wrong here?

It looks you are trying to embed the report specifying wrong token type. In your code token type is set to Embed:
tokenType: models.TokenType.Embed
While you never mention that such is generated (using GenerateTokenInGroup for example). So you are probably using the token acquired during initial authentication. If you want to use it, you should change token type to be Aad:
tokenType: models.TokenType.Aad
The difference is that Azure AD token gives access to user’s data, reports, dashboards and tiles, while embed token is specific to the embedded item. Also the embed token has shorter live (~5 minutes) than AAD token (~1 hour).

Related

How to hide s3 bucket and access key credentials from an Html file

I have an HTML web app running that uploads files into an s3 bucket.
There is logic written in javascript embedded into this html file. Within this script there are access keys passwords and the name of the bucket.
Anyone visiting the site can see this via a right click and inspecting the source.
Is there a way to mask this very sensitive information?
**********additional information
This is what you see via "inspect source"
<script>
bsCustomFileInput.init();
AWS.config.httpOptions.timeout = 0;
const s3 = new AWS.S3({
accessKeyId: 'asdfasdf23423sdfadf',
secretAccessKey: 'asdfasdf2342412341234234',
region: 'us-east-2'
});
var params = {
Bucket: 'Bucketname',
Can you post an example with dummy values of access keys only? As of the moment I cannot imagine if you have a post processing function or it is just a direct request after a click of an html element.
use temperary credentials and Policy to hide your bucket
I found a solution to this which involves using AWS lambda and AWS API gateway to generate a "presigned url".
The steps involved are detailed in this great tutorial.

How to get Microsoft graph access token from java spring

I tried to get graph api token from postman UI and was able to get planner data.
How to achieve same in java spring
I am not able to get access token for Microsoft graph api using java spring. I am able to get access token using postman.
I need to access planner API from one of the web application. As per Microsoft documentation I configured a app in azure active directory and got client key, secret key etc.
I also configured required permission to get groups and users.
Very first time I used below from POSTMAN
https://login.microsoftonline.com//oauth2/token with below data
client_id : <client_id from configured app>
client_secret : <client secret from configured app>
grant_type : client_credentials
resource : https://graph.microsoft.com
I got token, and I was able to get groups from https://graph.microsoft.com/v1.0/groups/
But same token was not valid for getting plans of group.
With lot of digging, I came to know that token accessed with client_credentials is not applicable to get data from planner API. So, next I used below details to get access token from UI of postman.
Grant Type : authorization_code
Callback URL : https://www.getpostman.com/oauth2/callback
Auth URL : https://login.microsoftonline.com/<tenant_id>/oauth2/authorize?resource=https://graph.microsoft.com
Access Token URL : https://login.microsoftonline.com/<tenant_id>/oauth2/v2.0/token
client_id : <client_id from configured app>
client_secret : <client secret from configured app>
I got the Microsoft login screen, and after successful login, I got token.
I could call planner API using this access token.
Now my question is how can I get this same token using java spring.
Also, my web app will be having background service running in scheduler calling graph API daily.
I do not want manual intervention here, but as told earlier, graph API will ask to login.
How to achieve above requirement.
private String getAuth() {
ConfidentialClientApplication app = null;
IClientCredential credential = ClientCredentialFactory.create(Appsecret);
try {
app = ConfidentialClientApplication.builder(MicrsoftAppId, credential).authority("https://login.microsoftonline.com/"+tenantId+"/").build();
}catch(MalformedURLException e) {
System.out.println(e.getMessage());
}
ClientCredentialParameters parameters = ClientCredentialParameters.builder(Collections.singleton("https://graph.microsoft.com/.default")).build();
CompletableFuture<IAuthenticationResult> future = app.acquireToken(parameters);
try {
IAuthenticationResult result = future.get();
return result.accessToken();
}catch(ExecutionException e){
System.out.println(e.getMessage());
}catch(InterruptedException e) {
System.out.println(e.getMessage());
}
return null;
}
Here you go! This code is made for application permission (so not delegated). It only requires your client Id and secret to operate. You will need the microsoft graph jar for it to work (and the many jars supporting it).

box-java-sdk - Normal Authentication

I am trying to build an application with Box SDK in Java. Currently, I am connecting to my Box with a developer token:
BoxAPIConnection api = new BoxAPIConnection("MY-DEVELOPER-TOKEN");
I have to generate a new developer token every 60 minutes, therefore I would like to make it so this is done automatically. According to the Box API authentication doc, we can do it with:
BoxAPIConnection api = new BoxAPIConnection("MY-CLIENT-ID", "MY-CLIENT-SECRET", "MY-AUTH-CODE");
However, I get:
Exception in thread "main" com.box.sdk.BoxAPIException: The API returned an error code: 400
{"error":"invalid_grant","error_description":"Auth code doesn't exist or is invalid for the client"}
I get my Client ID and Client Secret from the configuration page of my Box account, so I assume these are correct. Where can I get my authentication code? The one I am using is the one from a pop-up window when I first connected to my account.
You can get the authentication code like this:
go to a browser and type in with your client_id:
https://account.box.com/api/oauth2/authorize?response_type=code&client_id=xxxxxx&state&state=security_token%3DKnhMJatFipTAnM0nHlZA
authorize the app and you'll get a code back (make sure your redirect is something like localhost
then use postman and do this (fill in the code w/ what you just got back)

How to write a Java code to read fields from a website that requires login and uses POST request?

Need some help with fetching some data from a website.
Previously , we had following code in our application and it used to fetch the required data. We just used to read the required fields by forming a URL by passing username , password and search parameter (DEA number). The same URL (with parameters ) could also be hit from browser directly to see the results. It was a simple GET request:
{URL url = new URL(
"http://www.deanumber.com/Websvc/deaWebsvc.asmx/GetQuery?UserName="+getUsername()+"&Password="+getPassword()+"&DEA="
+ deaNumber
+ "&BAC=&BASC=&ExpirationDate=&Company=&Zip=&State=&PI=&MaxRows=");
Document document = parser.parse(url.toExternalForm());
// Ask the document for a list of all <sect1> tags it contains
NodeList sections = document.getElementsByTagName("DEA");
//Followed by a loop code to get each element by using sections.item(index).getFirstChild() etc.
}
Now, the website URL has got changed to following:
https://www.deanumber.com/RelId/33637/ISvars/default/Home.htm
I am able to login to the URL with credentials , go to the search page , enter the DEA number and search. The login page comes as a pop-up once I click 'Login' link on home page. Also, the final result comes as a pop-up. This is a POST request so I am unable to form the complete URL which I could use in my code.
I am not an expert in Web Services , but I think I need a web service URL like the one mentioned in the code above. Not sure how to get that !! Even if I get the URL , I am not sure how to perform the login through Java code and search the DEA number.
Also, it would be great if I could validate the URL manually before using in Java. Let me know if there is any way.
Or, in case there is any alternate approach in Java; kindly suggest.
Thanks in advance.
First of all, the previous approach provided by the website was completely wrong and insecure, because it passes the username and password as querystring parameters in plain text. I think, they would have realized this thing and changed their way of authentication.
Also, it looks like that they have restricted the direct URL based requests from the client applications like yours. For such requests from clients, they have published the web services. Check this link. They also have mentioned the rates for web service request counts.
So, you may need to open a formal communication channel to get authentication and other details to access their web services for this purpose. Depends on what they use for web service client authentication, you may code your client to access the web services.
I hope this helps.

specific IDs do not accept my access token in RestFB for Facebook

I try to fetch multiple objects through the RestFB API. I have a list of IDs (endpoints?) and want them to be bulk-fetched by RestFB. Therefore I use FacebookClient.fetchObjects(). The problem which now occurs is that one of the IDs in my list seems not to accept the token. I'm not that into the token system of facebook. The only token I generated is the app-token.
Two IDs used in the list:
working ID: 1104054513000418
not working ID: 1106761186063084
These IDs belong to posts which are from the same author and there is not real difference between them but the content.
Trying to fetch data by these IDs manually (no bulk-fetch) I have the same issue. So it is not an issue with the misusage of the multiple fetch method.
Code:
FacebookClient.AccessToken accessToken = new DefaultFacebookClient().obtainAppAccessToken(appId, appSecurity);
FacebookClient fbClient = new DefaultFacebookClient(accessToken.getAccessToken());
// consider filteredSocialItems as given
List<String> filteredItemIDs = filteredSocialItems.stream()
.map({ item -> item.properties.get("sourceId") })
.collect(Collectors.toList());
JsonObject json = fbClient.fetchObjects(filteredItemIDs, JsonObject.class, Parameter.with("fields", "name,id"));
Exception:
Caught: com.restfb.exception.FacebookOAuthException: Received Facebook error response of type OAuthException: (#100) Requires user session (code 100, subcode null)
com.restfb.exception.FacebookOAuthException: Received Facebook error response of type OAuthException: (#100) Requires user session (code 100, subcode null)
at com.restfb.DefaultFacebookClient$DefaultGraphFacebookExceptionMapper.exceptionForTypeAndMessage(DefaultFacebookClient.java:1201)
at com.restfb.DefaultFacebookClient.throwFacebookResponseStatusExceptionIfNecessary(DefaultFacebookClient.java:1122)
at com.restfb.DefaultFacebookClient.makeRequestAndProcessResponse(DefaultFacebookClient.java:1063)
at com.restfb.DefaultFacebookClient.makeRequest(DefaultFacebookClient.java:974)
at com.restfb.DefaultFacebookClient.makeRequest(DefaultFacebookClient.java:936)
at com.restfb.DefaultFacebookClient.fetchObjects(DefaultFacebookClient.java:431)
at facebookImageRefresh.run(facebookImageRefresh.groovy:48)
at com.intellij.rt.execution.CommandLineWrapper.main(CommandLineWrapper.java:48)
Solving the problem was a bit exhausting. It was an issue with an old facebook app version.
Facebook apps are created within your Facebook developer account
Since Facebook changed a lof of its API rules here lies the problem. You cannot just access a post by its ID like using 1104054513000418 you also have to prefix the ID of the page/user who created that post. So if your page's ID is 589476469431696 you actually need to create a combined ID out of both like 589476469431696_1104054513000418 -> "{page_id}_{post_id}". I have no idea if this is interchangeable.
So after creating a new app I was able to get this to work.
Another info: as I was looking for a user access token all the time - I found it within my facebook app advanced settings. But it seems I don't need it any more.

Categories

Resources