我的 Power BI 身份验证过程和 Web 请求有什么问题?
What is wrong with my Power BI Authentication process and webrequest?
最终编辑:答案已找到。这是一个依赖性问题。阅读下面的答案。
我正在开发一个程序,最终应该将数据从 SQL 服务器数据库实时推送到我们的 Power BI 报告。我目前正处于尝试从我的客户端应用程序连接到我的 Power BI 的阶段。
对于身份验证过程,我已按照以下代码示例进行操作:
https://gist.github.com/dquig/a4f2f02fe3e306cebe2e
身份验证似乎工作正常。我得到了一个访问令牌(每次都是一样的,我还没有发现这是否是应该的)。编辑:我还检查了 OAuth2、powerBI API 的所有 msdn 页面(包括 Azure Active Directory 步骤)。
编辑:我刚刚注意到,如果我填写完全是胡说八道,我什至会得到一个访问令牌(为什么我以前不尝试这个...)。我每次得到的都是相同的标记。 Web 请求的响应具有 200 状态,但实体为空。
这是我的身份验证代码(我在这里省略了请求):
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import com.microsoft.aad.adal4j.AuthenticationContext;
public class PowerBIController {
private static final String POWER_BI_BASE_URL = "https://api.powerbi.com";
private static final String AUTH_URI = "https://login.windows.net/common/oauth2/authorize";
private static final String RESOURCE_URI = "https://analysis.windows.net/powerbi/api";
private static final boolean VALIDATE_AUTHORITY = false;
private static final String NATIVE_CLIENT_ID = "4b2f0d69-c17d-4d61-b2c0-4aeee5dfffe8";
private static final String USER_AT_TENANT = "powerBIUser@pveermanvicrea.onmicrosoft.com";
private static final String PASSWORD = "****";
private AuthenticationContext context = null;
private Client client;
private ExecutorService service = null;
private Response response;
public PowerBIController() throws Exception {
client = ClientBuilder.newClient();
service = Executors.newSingleThreadExecutor();
context = new AuthenticationContext(AUTH_URI, VALIDATE_AUTHORITY, service);
String powerBIAccessToken = getToken(RESOURCE_URI, NATIVE_CLIENT_ID, USER_AT_TENANT, PASSWORD);
}
private String getToken(String resourceUri, String nativeClientId,
String tenant, String password) throws ExecutionException, InterruptedException{
return context.acquireToken(
resourceUri,
nativeClientId,
tenant,
password,
null
).get().getAccessToken();
}
然后是http请求:
我尝试复制粘贴整个示例(来自上面的 link),但 readEntity 不是 Response 的方法。我在这个 Read response body in JAX-RS client from a post request 上找到了以下 post。但我使用的是 javax.ws.rs 的 2.0 版。所以,这对我来说有点困惑。
public PowerBIController() throws Exception {
client = ClientBuilder.newClient();
service = Executors.newSingleThreadExecutor();
context = new AuthenticationContext(AUTH_URI, VALIDATE_AUTHORITY, service);
String powerBIAccessToken = getToken(RESOURCE_URI, NATIVE_CLIENT_ID, USER_AT_TENANT, PASSWORD);
post(biTarget, powerBIAccessToken);
}
private void post(WebTarget biTarget, String powerBIAccessToken) throws URISyntaxException, IOException, ExecutionException, InterruptedException {
Response response = target
Invocation.Builder builder = biTarget.request(MediaType.APPLICATION_JSON);
Invocation.Builder header = builder.header("Authorization",
"Bearer " + powerBIAccessToken);
response = header.get();
System.out.println("header: " + header.toString());
System.out.println("status: " + response.getStatus());
System.out.println("body:" + response.readEntity(String.class));
}
我在 http://docs.powerbi.apiary.io/ 查过。在这里,我必须登录到我的 Office 365 帐户,然后我可以使用相同的代码来获取数据集列表。在这里我不必进行身份验证,这可能会有所不同,但是当我 运行 作为调试时,我可以清楚地看到我有一个访问令牌。
这是他们说可以正确调用 get 请求的代码。显然这行不通我也很确定目标有错别字:
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.MediaType;
Client client = ClientBuilder.newClient();
Response response = client.target("https://api.powerbi.com/beta/myorghttps://api.powerbi.com/beta/myorg/datasets{?defaultRetentionPolicy}")
.request(MediaType.TEXT_PLAIN_TYPE)
.header("undefined", "")
.get();
System.out.println("status: " + response.getStatus());
System.out.println("headers: " + response.getHeaders());
System.out.println("body:" + response.readEntity(String.class));
我已经尝试使用 Fiddler 来查看当我 运行 时实际发生了什么。但是,Fiddler 根本没有显示 activity(即使我检查了 https 选项)。
最后,这是我对这段代码的依赖:
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>javax.ws.rs-api</artifactId>
<version>2.0</version>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-client</artifactId>
<version>3.0.2.Final</version>
</dependency>
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>adal4j</artifactId>
<version>1.0.0</version>
</dependency>
我真的很期待任何帮助。如果我的问题有任何问题,请说出来。我尽我最大的努力让自己清楚并遵守这个论坛的规则,但我可能漏掉了一些东西。
非常感谢
回答:我的部分程序也使用了 azure-media 0.6.0。这包括球衣核心 1.3.1。结论:即使我认为我是从 javax.ws.rs 2.0 导入的(如果您查看类型,它甚至会说)它实际上是从 jersey 1.3.1 获取其对象定义。这不仅仅适用于 azure-media 依赖项。
所以我将 post 需要排除的依赖项和必要的最终依赖项。
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-management</artifactId>
<version>0.7.0</version>
<exclusions>
<exclusion>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-client</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-json</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-servicebus</artifactId>
<version>0.7.0</version>
<exclusions>
<exclusion>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-client</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-json</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-serviceruntime</artifactId>
<version>0.6.0</version>
<exclusions>
<exclusion>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-client</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-json</artifactId>
</exclusion>
</exclusions>
</dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-media</artifactId>
<version>0.6.0</version>
<exclusions>
<exclusion>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-client</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-json</artifactId>
</exclusion>
</exclusions>
</dependency>
必要的依赖:
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-client</artifactId>
<version>3.0.2.Final</version>
</dependency>
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>adal4j</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-client</artifactId>
<version>2.19</version>
</dependency>
</dependencies>
这是打字错误吗?
Response response =client.target("https://api.powerbi.com/beta/myorghttps://api.powerbi.com/beta/myorg/datasets{?defaultRetentionPolicy}")
这是一篇完整的分步文章:https://msdn.microsoft.com/en-US/library/dn877545.aspx,对于 Power BI 身份验证,请参阅 'What you need to authenticate a Power BI client app' 部分。
所以,问题是我使用了几个 Maven 依赖项,它们在层次结构中具有部分重叠的依赖项。
例如,我包括了 Jersey 客户端 v2.1.9 以及使用 Jersey 客户端 v1.13 的 Microsoft windows azure API。
这个答案的关键点如下:当您使用 Azure SDK 和 Power BI REST API 时,您很可能会弄乱依赖关系。检查您的依赖关系层次结构以查看哪些依赖关系被多次使用。
最终编辑:答案已找到。这是一个依赖性问题。阅读下面的答案。
我正在开发一个程序,最终应该将数据从 SQL 服务器数据库实时推送到我们的 Power BI 报告。我目前正处于尝试从我的客户端应用程序连接到我的 Power BI 的阶段。
对于身份验证过程,我已按照以下代码示例进行操作: https://gist.github.com/dquig/a4f2f02fe3e306cebe2e 身份验证似乎工作正常。我得到了一个访问令牌(每次都是一样的,我还没有发现这是否是应该的)。编辑:我还检查了 OAuth2、powerBI API 的所有 msdn 页面(包括 Azure Active Directory 步骤)。
编辑:我刚刚注意到,如果我填写完全是胡说八道,我什至会得到一个访问令牌(为什么我以前不尝试这个...)。我每次得到的都是相同的标记。 Web 请求的响应具有 200 状态,但实体为空。
这是我的身份验证代码(我在这里省略了请求):
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import com.microsoft.aad.adal4j.AuthenticationContext;
public class PowerBIController {
private static final String POWER_BI_BASE_URL = "https://api.powerbi.com";
private static final String AUTH_URI = "https://login.windows.net/common/oauth2/authorize";
private static final String RESOURCE_URI = "https://analysis.windows.net/powerbi/api";
private static final boolean VALIDATE_AUTHORITY = false;
private static final String NATIVE_CLIENT_ID = "4b2f0d69-c17d-4d61-b2c0-4aeee5dfffe8";
private static final String USER_AT_TENANT = "powerBIUser@pveermanvicrea.onmicrosoft.com";
private static final String PASSWORD = "****";
private AuthenticationContext context = null;
private Client client;
private ExecutorService service = null;
private Response response;
public PowerBIController() throws Exception {
client = ClientBuilder.newClient();
service = Executors.newSingleThreadExecutor();
context = new AuthenticationContext(AUTH_URI, VALIDATE_AUTHORITY, service);
String powerBIAccessToken = getToken(RESOURCE_URI, NATIVE_CLIENT_ID, USER_AT_TENANT, PASSWORD);
}
private String getToken(String resourceUri, String nativeClientId,
String tenant, String password) throws ExecutionException, InterruptedException{
return context.acquireToken(
resourceUri,
nativeClientId,
tenant,
password,
null
).get().getAccessToken();
}
然后是http请求: 我尝试复制粘贴整个示例(来自上面的 link),但 readEntity 不是 Response 的方法。我在这个 Read response body in JAX-RS client from a post request 上找到了以下 post。但我使用的是 javax.ws.rs 的 2.0 版。所以,这对我来说有点困惑。
public PowerBIController() throws Exception {
client = ClientBuilder.newClient();
service = Executors.newSingleThreadExecutor();
context = new AuthenticationContext(AUTH_URI, VALIDATE_AUTHORITY, service);
String powerBIAccessToken = getToken(RESOURCE_URI, NATIVE_CLIENT_ID, USER_AT_TENANT, PASSWORD);
post(biTarget, powerBIAccessToken);
}
private void post(WebTarget biTarget, String powerBIAccessToken) throws URISyntaxException, IOException, ExecutionException, InterruptedException {
Response response = target
Invocation.Builder builder = biTarget.request(MediaType.APPLICATION_JSON);
Invocation.Builder header = builder.header("Authorization",
"Bearer " + powerBIAccessToken);
response = header.get();
System.out.println("header: " + header.toString());
System.out.println("status: " + response.getStatus());
System.out.println("body:" + response.readEntity(String.class));
}
我在 http://docs.powerbi.apiary.io/ 查过。在这里,我必须登录到我的 Office 365 帐户,然后我可以使用相同的代码来获取数据集列表。在这里我不必进行身份验证,这可能会有所不同,但是当我 运行 作为调试时,我可以清楚地看到我有一个访问令牌。 这是他们说可以正确调用 get 请求的代码。显然这行不通我也很确定目标有错别字:
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.MediaType;
Client client = ClientBuilder.newClient();
Response response = client.target("https://api.powerbi.com/beta/myorghttps://api.powerbi.com/beta/myorg/datasets{?defaultRetentionPolicy}")
.request(MediaType.TEXT_PLAIN_TYPE)
.header("undefined", "")
.get();
System.out.println("status: " + response.getStatus());
System.out.println("headers: " + response.getHeaders());
System.out.println("body:" + response.readEntity(String.class));
我已经尝试使用 Fiddler 来查看当我 运行 时实际发生了什么。但是,Fiddler 根本没有显示 activity(即使我检查了 https 选项)。
最后,这是我对这段代码的依赖:
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>javax.ws.rs-api</artifactId>
<version>2.0</version>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-client</artifactId>
<version>3.0.2.Final</version>
</dependency>
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>adal4j</artifactId>
<version>1.0.0</version>
</dependency>
我真的很期待任何帮助。如果我的问题有任何问题,请说出来。我尽我最大的努力让自己清楚并遵守这个论坛的规则,但我可能漏掉了一些东西。
非常感谢
回答:我的部分程序也使用了 azure-media 0.6.0。这包括球衣核心 1.3.1。结论:即使我认为我是从 javax.ws.rs 2.0 导入的(如果您查看类型,它甚至会说)它实际上是从 jersey 1.3.1 获取其对象定义。这不仅仅适用于 azure-media 依赖项。
所以我将 post 需要排除的依赖项和必要的最终依赖项。
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-management</artifactId>
<version>0.7.0</version>
<exclusions>
<exclusion>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-client</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-json</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-servicebus</artifactId>
<version>0.7.0</version>
<exclusions>
<exclusion>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-client</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-json</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-serviceruntime</artifactId>
<version>0.6.0</version>
<exclusions>
<exclusion>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-client</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-json</artifactId>
</exclusion>
</exclusions>
</dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-media</artifactId>
<version>0.6.0</version>
<exclusions>
<exclusion>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-client</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-json</artifactId>
</exclusion>
</exclusions>
</dependency>
必要的依赖:
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-client</artifactId>
<version>3.0.2.Final</version>
</dependency>
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>adal4j</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-client</artifactId>
<version>2.19</version>
</dependency>
</dependencies>
这是打字错误吗?
Response response =client.target("https://api.powerbi.com/beta/myorghttps://api.powerbi.com/beta/myorg/datasets{?defaultRetentionPolicy}")
这是一篇完整的分步文章:https://msdn.microsoft.com/en-US/library/dn877545.aspx,对于 Power BI 身份验证,请参阅 'What you need to authenticate a Power BI client app' 部分。
所以,问题是我使用了几个 Maven 依赖项,它们在层次结构中具有部分重叠的依赖项。
例如,我包括了 Jersey 客户端 v2.1.9 以及使用 Jersey 客户端 v1.13 的 Microsoft windows azure API。
这个答案的关键点如下:当您使用 Azure SDK 和 Power BI REST API 时,您很可能会弄乱依赖关系。检查您的依赖关系层次结构以查看哪些依赖关系被多次使用。