からめもぶろぐ。

俺たちは雰囲気で OAuth をやっている

PowerShell モジュール開発入門を公開しました

なんとなく書いたもののしゃべる機会がなくなりそうだったのでスライドだけ公開します。
PowerShell モジュールを Azure Artifacts に公開する方法については以前の記事でも公開していますが、今回はより全体的に、コーディング、テスト、CI/CD の観点から PowerShell モジュールを開発する方法について述べています。

Easy Auth を設定した Azure Functions を Power Automate から呼び出す

Azure Functions はセキュリティを高めるために標準で API キーを渡して実行することができますが、より高いセキュリティを求める場合に、Azure Active Directory による認証 (Easy Auth) をかけることがあると思います。また、Azure Functions の HTTP トリガーの関数を UI (ブラウザーの遷移) で呼び出すことはほとんどなく、JavaScript のリクエストや Power Automate の HTTP アクションなどの UI が存在しないところから呼び出すことになります。その場合、OAuth で Azure Active Directory の認証および承認を通す必要がありますが、毎度ながら OAuth の仕組みは難しいので、順を追ってやり方を見てみたいと思います。

手順

Azure Functions の設定

Easy Auth を有効にするために、呼び出し先の Azure Functions で [プラットフォーム機能] - [ネットワーク] - [承認/認証] をクリックします。

[App Service 認証] をオンにし、[認証プロバイダー] として「Azure Active Directory」を選択します。アプリの作成が要求されるので、簡易モードでアプリを作成します。


Azure Active Directory のアプリの登録

Easy Auth を有効にするために作成したアプリとは別に新しいアプリを作成します。新しいアプリで [API のアクセス許可] で検索すると、Easy Auth を有効にしたときのアプリが出てくるので、「user_impersonation」をチェックし、アクセス許可を追加します。


リフレッシュ トークンの取得

Power Automate を使って、作成した新しいアプリに対してのアクセス トークンおよびリフレッシュ トークンを取得します。手順については以下の記事にまとまっているのでこちらを参考にしてください。

qiita.com

ここでは、ブラウザー経由で認証コードを取得し、アクセス トークンを OneDrive for Bussiness (先の記事では OneDrive になっていますが OneDrive for Bussiness に読み替えてください) に保存するフローを実行したとします。

Azure Functions の呼び出し

OneDrive for Bussiness に保存されたリフレッシュ トークンからアクセス トークンを取得し、アクセス トークンを Authorization ヘッダーに追加して Azure Functions の HTTP トリガーを呼び出します。

実行してみると、HTTP トリガーが正常に呼び出され結果が返ってくるのがわかります。


まとめ

今回の手順は App Service で自作の Web API を Azure Active Directory で保護する手順と同じになります。アプリが 2 種類出てくるので混乱しがちですが「アクセス許可を定義する」アプリと「アクセス許可を付与する」アプリがあることを理解するとよいのではないかと思います。

SharePoint Framework を使ってメール送信フォームを作ってみる

かなり以前の記事になりますが、SharePoint の Web パーツを使ってメール送信フォームを作ったことがありました。

blog.karamem0.jp

今回はこの記事のアップデート版となります。現在の SharePoint 開発のスタンダードである SharePoint Framework を使って Web パーツを作成し、Microsoft Graph でメールを送るというものになります。

サンプル コード

github.com

今回はフレームワークとして React を使用します。React を使用した場合、Office UI Fablic および PnP SPFx Controls が使えますので、開発生産性が格段に上がります。

MyApplicationWebPart.ts

React を使った SharePoint Framework 開発の定番として、Component の props に context を渡すというのがあります。これをやっておかないと、Component 側で Microsoft Graph の呼び出しなど、いろいろなことができなくなってしまいます。テンプレートからプロジェクトを作ったときにはこのロジックは入っていませんので、はじめにやっておくようにします。

export default class MyApplicationWebPart extends BaseClientSideWebPart<IMyApplicationWebPartProps> {

  public render(): void {
    const element: React.ReactElement<IMailFormProps> = React.createElement(
      MailForm,
      {
        context: this.context,
      }
    );

    ReactDom.render(element, this.domElement);
  }

}

MailForm.tsx

PnP SPFx Controls には PeoplePicker という便利なコントロールが用意されているので宛先フィールドにはこれを利用します。それ以外は Office UI Fabric の TextField を使いました。入力された値は state に入れるようにします。送信ボタンがクリックされたときに、state の値を使って Microsoft Graph の sendMail メソッドを使ってメールを送るようにします。

import * as React from 'react';
import { MSGraphClient } from '@microsoft/sp-http';
import { IMailFormProps } from './IMailFormProps';
import { IMailFormState } from './IMailFormState';
import styles from './MailForm.module.scss';
import * as strings from 'MyApplicationWebPartStrings';
import { PeoplePicker, PrincipalType } from '@pnp/spfx-controls-react/lib/PeoplePicker';
import { TextField } from 'office-ui-fabric-react/lib/TextField';
import { PrimaryButton } from 'office-ui-fabric-react/lib/Button';

export default class MyApplication extends React.Component<IMailFormProps, IMailFormState> {

  constructor(props) {
    super(props);
    this.state = {
      to: [],
      subject: "",
      body: ""
    };
  }

  public render(): React.ReactElement<IMailFormProps> {
    return (
      <div className={styles.mailform}>
        <div className={styles.container}>
          <PeoplePicker
            context={this.props.context}
            titleText="宛先"
            personSelectionLimit={99}
            principalTypes={[PrincipalType.User]}
            selectedItems={value => this.setState({ to: value })} />
          <TextField
            label="件名"
            value={this.state.subject}
            onChanged={value => this.setState({ subject: value })} />
          <TextField
            label="本文"
            multiline
            rows={10}
            onChanged={value => this.setState({ body: value })} />
          <div className={styles.buttons}>
          <PrimaryButton
              text="送信"
              onClick={this._onSendButtonClick.bind(this)} />
          </div>
        </div>
      </div>
    );
  }

  private _onSendButtonClick(): void {
    this.props.context.msGraphClientFactory
      .getClient()
      .then((client: MSGraphClient) => {
        client.api('/me/sendMail').post(
          {
            message: {
              toRecipients: this.state.to.map(value => { return { emailAddress: { address: value.secondaryText } }; }),
              subject: this.state.subject,
              body: {
                content: this.state.body,
                contentType: 'text'
              }
            }
          },
          (error: any, response: any, rawResponse: any) => {
            if (error) {
              window.alert("メールを送信できませんでした。");
            } else {
              window.alert("メールを送信しました。");
            }
          });
      });
  }

}

実行

実行してみます。モダン UI と調和性の取れたレイアウトで表示されているのがわかると思います。

Office UI Fablic と PnP SPFx Controls の恩恵を受けられるのは非常に大きいので、ぜひ React を使って SPFx 開発を楽しんでいただけたらと思います。

SPClientCore 3.2.0 を公開しました

SPClientCore 3.2.0 を公開しました。

SPClientCore は PowerShell Core 向けの SharePoint Online 管理モジュールです。

www.powershellgallery.com

ユーザー プロパティおよびハブ サイトに関するコマンドレットを追加しました。
提供されているコマンドレットの数は 225 になりました。

Power Platform + Azure で SharePoint のサイト作成フォームを作ってみる

2020/01/31 に行われた「Power Apps でローコーディングな勉強会 #12」に参加してきました。

powerapps.connpass.com

その際にちょっとしたアプリを作成したのでここで紹介したいと思います。

概要

アプリの概要としては「Power Apps から SharePoint のサイト コレクションを作成する」というものです。SharePoint のサイト コレクションは GUI で作成する以外では PowerShell または CSOM (C#) による作成が可能になっています。今回は、Azure Automation で PowerShell を実行することによって、サイト コレクションの作成を実現しました。

Azure Automation

まずは事前準備として Azure Automation で SharePoint Online Management Shell を使うためにモジュールをインストールする必要があります。モジュールはギャラリーから検索してインストールすることができます。

次に Runbook を作成します。事前に用意しておいた資格情報で接続し New-SPOSite を実行するだけの簡単なものです。


Power Apps

Azure Automation に渡す情報を入力するためのフォームを作成します。あまり時間がなかったのでバリデーションなんかのチェックは入っていません。こういう場合のバリデーションはどうやってやるんですかね?まだまだ Power Apps スキル不足を感じます。


Power Automate

Power Apps で入力後、ボタンをクリックしたときに動作する Power Automate を定義します。ここでは単純に Power Apps から受け取ったパラメーターを Azure Automation に受け渡しています。


実行

実行してみるとサイト コレクションが作成できていることがわかります。


まとめ

今回は単純に Power Automate は Azure Automation を呼ぶだけでしたが、承認フローを入れたり、作成後にメールや Teams に通知する機能を付けたりと、もっといろいろなことができると思います。また、Power Automate から Azure Automation を呼び出すというテクニックは、ほかの場面でも応用が効くと思いますので、ぜひとも使っていただきたいと思います。