SharePoint Framework で Common Data Service のデータを読み取る
はじめに
SharePoint Framework では AadHttpClient を使うことで Azure AD で保護された API に対してのアクセスを簡単に実装できます。同じ Azure AD で保護されている Common Data Service (Dynamics 365) のデータにもアクセスできるため、今回はその方法を解説します。
事前準備
Web API へのアクセス許可を与えるには、package-solution.json に webApiPermissionRequests を記述します。この記述に従い、SharePoint 管理センターで API のアクセス許可を承認できるようになります。しかし、Common Data Service の場合、次のように記述してもうまくいきません。
{
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/package-solution.schema.json",
"solution": {
"name": "SampleApplication",
"id": "ad9139c7-12db-470b-937d-54967f418959",
"version": "1.0.0.0",
"includeClientSideAssets": true,
"isDomainIsolated": false,
"webApiPermissionRequests": [
{
"resource": "Common Data Service",
"scope": "user_impersonation"
}
]
},
"paths": {
"zippedPackage": "solution/sharepoint-framework-read-dynamics.sppkg"
}
}
これは、Common Data Service という名前のサービス プリンシパルが複数存在し、表示名で紐づけしようとすると別のサービス プリンシパルに結びついてしまうことが原因のようです。SharePoint Framework の問題ですが、公式でも表示名を指定するように注釈があるため、何らかの理由があると考えられます。
resource プロパティの値には、アクセス許可を要求するアプリケーションの displayName を指定する必要があります。リソースの指定に objectId を使用すると、アクセス許可の要求を承認しようとしたときにエラーが発生します。
このため、Common Data Service へのアクセス許可を与えるには、Azure ポータルで操作する必要があります。SharePoint Framework は SharePoint Online Client Extensibility Web Application Principal を使用します。このアプリケーションを編集することで、SharePoint 管理ポータルでの承認と同じことができます。
SharePoint 管理ポータルから見た場合も、承認された要求として表示されます。ただし、SharePoint Framework のアプリ名などのメタ情報は表示されません。
これで Common Data Service に接続できます。
サンプル コード
実行手順
src/webparts/my-application/SampleApplicationWebPart.ts
context を渡すことを忘れないようにしてください。endpoint は Dynamics 365 の URL を指定します。
export default class SampleApplicationWebPart extends BaseClientSideWebPart<ISampleApplicationWebPartProps> {
public render(): void {
const element: React.ReactElement<ISampleApplicationProps> = React.createElement(
SampleApplication,
{
context: this.context,
endpoint: this.properties.endpoint
}
);
ReactDom.render(element, this.domElement);
}
}
src/webparts/my-application/components/SampleApplication.tsx
componentDidMount メソッドで AadHttpClient を使い、Common Data Service Web API へのリクエストを実行します。今回は標準のエンティティのデータを取得しますが、カスタムエンティティについても同様に取得可能です。
export default class SampleApplication extends React.Component<ISampleApplicationProps, ISampleApplicationState> {
public componentDidMount(): void {
if (this.props.endpoint == null) {
return;
}
this.props.context.aadHttpClientFactory
.getClient(this.props.endpoint)
.then((client: AadHttpClient) => {
client
.get(this.props.endpoint + "/api/data/v9.0/accounts", AadHttpClient.configurations.v1)
.then((response: HttpClientResponse) => response.json())
.then((response: any) => {
this.setState({ accounts: response.value as Array<IAccount> });
});
});
}
}
実行結果
実行すると、以下のようにエンティティのデータが取得できていることを確認できます。なお、Common Data Service のライセンス (Power Apps や Dynamics 365 Sales など) がないユーザーの場合は表示できませんので注意してください。
おわりに
直接 Azure AD のアプリケーションを操作する方法は少しトリッキーですが、使えるテクニックなのでぜひ試してみてください。
Discussion