powerbi 用户名密码认证和服务主体认证区别
1. 主要区别
主要区别在于token的作用域不同。
1.1 用户密码
通过用户名称和密码可以直接获取一个access_token(代码见下面),这个token可以用于powerbi 报表和数据集的所有操作;
1.2 服务主体认证
先生成一个acess_token,这个token有获取所有报表属性的权限,没有嵌入报表、新增、编辑报表的权限;
根据这个access_token 和下面的API可以生成新的token,用于嵌入报表、新增、编辑报表,API翻译如下: 注意:需要.com改成.cn
OPERATIONS
1.Dashboards GenerateTokenInGroup // 创建一个token,用于查看指定的dashboard
POST https://api.powerbi.com/v1.0/myorg/groups/{groupId}/dashboards/{dashboardId}/GenerateToken
// 嵌入报表
2.Datasets GenerateTokenInGroup // 创建一个token,用于嵌入报表在指定的数据集
POST https://api.powerbi.com/v1.0/myorg/groups/{groupId}/datasets/{datasetId}/GenerateToken
BODY {"accessLevel":"Create/Edit/View","allowSaveAs":true} 【Create报错】
3.Generate Token // 为多个报表、数据、工作空间,创建一个token,
POST https://api.powerbi.com/v1.0/myorg/GenerateToken
// 新增报表
4.Reports GenerateTokenForCreateInGroup // 创建一个token,用于创建报表在指定的数据集
POST https://api.powerbi.com/v1.0/myorg/groups/{groupId}/reports/GenerateToken
BODY {"accessLevel":"Create/Edit/View","allowSaveAs":true,"datasetId":"必填"}
// 查看或编辑报表
5.Reports GenerateTokenInGroup // 创建一个token,用于查看或编辑指定的报表
POST https://api.powerbi.com/v1.0/myorg/groups/{groupId}/reports/{reportId}/GenerateToken
BODY {"accessLevel":"Create/Edit/View","allowSaveAs":true}
原文参考 https://docs.microsoft.com/en-us/rest/api/power-bi/embedtoken/dashboards_generatetokeningroup
2.用户名密码获取token代码
public String
getPasswordToken() {
String token
= "";
String url
= "https://login.partner.microsoftonline.cn/common/oauth2/token";
Map
<String, String> header
= new HashMap<>(4);
header
.put("Content-Type", "application/x-www-form-urlencoded");
header
.put("Accept", "*/*");
Map
<String, String> body
= new HashMap<>(16);
body
.put("resource", "https://analysis.chinacloudapi.cn/powerbi/api");
body
.put("client_id", "xxx");
body
.put("client_secret", "xxx");
body
.put("grant_type", "password");
body
.put("username", "xxx");
body
.put("password", "xxx");
StringBuilder bodyStr
= new StringBuilder();
int i
= 0;
for (Map
.Entry
<String, String> entry
: body
.entrySet()) {
i
++;
bodyStr
.append(entry
.getKey()).append("=").append(entry
.getValue());
if (i
< body
.size()) {
bodyStr
.append("&");
}
}
String baseStr
= httpUtil
.doPost(url
, header
, bodyStr
.toString());
JSONObject jsonObject
= JSONObject
.parseObject(baseStr
);
token
= jsonObject
.getString("access_token");
return token
;
}
3. 服务主体认证获取token
3.1 controller
@ApiOperation("生成all Token用于powerbi操作")
@GetMapping("/bi/all/token")
public Result
allToken(
@ApiParam(value
= "数据类型", required
= true) @RequestParam("type") String type
,
@ApiParam(value
= "数据id") @RequestParam(value
= "id",required
= false) String id
,
@ApiParam(value
= "token类型") @RequestParam(value
= "level",required
= false) String level
) throws Exception
{
return powerBiService
.allToken(type
, id
, level
);
}
3.2 service
Result
allToken(String type
, String id
, String level
) throws Exception
;
3.3 serviceImpl
@Override
public Result
allToken(String type
, String id
, String level
) throws Exception
{
String token
= "";
if ("report".equals(type
)) {
List
<String> operator
= Arrays
.asList("View", "Edit");
if (operator
.contains(level
)) {
token
= powerBIUtil
.generateTokenByReportId(id
, level
);
}
} else if ("accessToken".equals(type
)) {
token
= powerBIUtil
.getEmailToken();
} else if ("all".equals(type
)) {
token
= powerBIUtil
.generateTokenByDatasetIds(id
);
} else if ("dataset".equals(type
) && "Create".equals(level
)) {
token
= powerBIUtil
.generateTokenByDatasetId(id
, level
);
}
return Result
.d(token
);
}
3.4 powerBIUtil
public String
getEmailToken() {
String token
= "";
String url
= "https://login.chinacloudapi.cn/a6c1b34e-d17f-48de-83b8-8e248b0f0360/oauth2/token";
Map
<String, String> header
= new HashMap<>(16);
header
.put("Content-Type", "application/x-www-form-urlencoded");
header
.put("Accept", "*/*");
Map
<String, String> body
= new HashMap<>(16);
body
.put("grant_type", "client_credentials");
body
.put("resource", "https://analysis.chinacloudapi.cn/powerbi/api");
body
.put("client_id", "xxx");
body
.put("client_secret", "xxx");
StringBuilder bodyStr
= new StringBuilder();
int i
= 0;
for (Map
.Entry
<String, String> entry
: body
.entrySet()) {
i
++;
bodyStr
.append(entry
.getKey()).append("=").append(entry
.getValue());
if (i
< body
.size()) {
bodyStr
.append("&");
}
}
String baseStr
= httpUtil
.doPost(url
, header
, bodyStr
.toString());
JSONObject jsonObject
= JSONObject
.parseObject(baseStr
);
token
= jsonObject
.getString("access_token");
return token
;
}
public String
generateTokenByReportId(String id
, String level
) throws Exception
{
String url
= "https://api.powerbi.cn/v1.0/myorg/groups/fecd78a9-73f5-49c9-ae8d-40bd3590112e/reports/";
url
= url
+ id
;
url
= url
+ "/GenerateToken";
JSONObject body
= new JSONObject();
body
.put("accessLevel", level
);
body
.put("allowSaveAs", "true");
String accessToken
= getToken();
String baseStr
= httpUtil
.postByUrlAndToken(url
,accessToken
, body
);
JSONObject jsonObject
= JSONObject
.parseObject(baseStr
);
return jsonObject
.getString("token");
}
public String
generateTokenByDatasetId(String datasetId
, String level
) throws Exception
{
String url
= "https://api.powerbi.cn/v1.0/myorg/groups/fecd78a9-73f5-49c9-ae8d-40bd3590112e/reports/GenerateToken";
JSONObject body
= new JSONObject();
body
.put("accessLevel", level
);
body
.put("allowSaveAs", "true");
body
.put("datasetId", datasetId
);
String accessToken
= getToken();
String baseStr
= httpUtil
.postByUrlAndToken(url
,accessToken
, body
);
JSONObject jsonObject
= JSONObject
.parseObject(baseStr
);
return jsonObject
.getString("token");
}
public String
generateTokenByDatasetIds(String datasetId
) throws Exception
{
String url
= "https://api.powerbi.cn/v1.0/myorg/GenerateToken";
JSONObject body
= new JSONObject();
List
<JSONObject> list
= new ArrayList<>();
JSONObject dataSet
= new JSONObject();
dataSet
.put("id", datasetId
);
list
.add(dataSet
);
body
.put("datasets", list
);
String accessToken
= getToken();
String baseStr
= httpUtil
.postByUrlAndToken(url
,accessToken
, body
);
JSONObject jsonObject
= JSONObject
.parseObject(baseStr
);
return jsonObject
.getString("token");
}
3.5 HttpUtil
import com
.alibaba
.fastjson
.JSONObject
;
import lombok
.extern
.log4j
.Log4j
;
import org
.springframework
.stereotype
.Component
;
import java
.io
.BufferedReader
;
import java
.io
.InputStream
;
import java
.io
.InputStreamReader
;
import java
.io
.OutputStreamWriter
;
import java
.io
.PrintWriter
;
import java
.net
.HttpURLConnection
;
import java
.net
.URL
;
import java
.util
.Map
;
private static final int TWOTHOUSAND
= 20000;
public String
doPost(String url
, Map
<String, String> header
, String body
) {
String result
= "";
BufferedReader in
= null
;
PrintWriter out
= null
;
try {
URL realUrl
= new URL(url
);
HttpURLConnection connection
= (HttpURLConnection
) realUrl
.openConnection();
connection
.setRequestMethod("POST");
for (Map
.Entry
<String, String> entry
: header
.entrySet()) {
connection
.setRequestProperty(entry
.getKey(), entry
.getValue());
}
connection
.setDoOutput(true);
connection
.setDoInput(true);
connection
.setConnectTimeout(TWOTHOUSAND
);
connection
.setReadTimeout(TWOTHOUSAND
);
try {
out
= new PrintWriter(connection
.getOutputStream());
out
.print(body
);
out
.flush();
} catch (Exception e
) {
e
.printStackTrace();
}
try {
in
= new BufferedReader(new InputStreamReader(connection
.getInputStream(), "UTF-8"));
String line
;
while ((line
= in
.readLine()) != null
) {
result
+= line
;
}
in
.close();
connection
.disconnect();
} catch (Exception e
) {
e
.printStackTrace();
}
} catch (Exception e
) {
e
.printStackTrace();
}
return result
;
}
public String
postByUrlAndToken(String defURL
, String token
, JSONObject body
) throws Exception
{
URL url
= new URL(defURL
);
HttpURLConnection con
= (HttpURLConnection
) url
.openConnection();
con
.setRequestMethod("POST");
con
.setUseCaches(false);
con
.setDoInput(true);
con
.setDoOutput(true);
con
.setRequestProperty("Content-Type", "application/json");
con
.setRequestProperty("Accept", "*/*");
con
.setRequestProperty("Authorization", "Bearer " + token
);
con
.connect();
// 得到请求的输出流对象
OutputStreamWriter writer
= new OutputStreamWriter(con
.getOutputStream(), "UTF-8");
writer
.write(body
.toString());
writer
.flush();
// 获取服务端响应,通过输入流来读取URL的响应
InputStream is
= con
.getInputStream();
BufferedReader reader
= new BufferedReader(new InputStreamReader(is
, "UTF-8"));
StringBuffer sbf
= new StringBuffer();
String strRead
= null
;
while ((strRead
= reader
.readLine()) != null
) {
sbf
.append(strRead
);
sbf
.append("\r\n");
}
reader
.close();
is
.close();
// 关闭连接
con
.disconnect();
return sbf
.toString();
}