SharePoint Add-ins: On-Premises と Office 365 で動く Add-in を作成するには (Authentication)

※この投稿は Office 365 Advent Calendar 2012 に参加しています。

SharePoint Add-ins 開発

こんにちは。

Olivers さんの投稿 に引き続き、私も開発系のネタを紹介したいと思います。
今回は、構築したアプリケーションを Office 365 と On-Premises の双方で動作させるために必要な知識やコツについて紹介したいと思います。

SharePoint Server 2013 の On-Premise 環境で Cloud hosted (Autohosted、Provider-hosted) を使用する場合、いろいろと制限が出てきます。
例えば、Azure 上のサーバー コードから SharePoint に接続する場合を想像してみてください。Proxy や Firewall を超えて、On-Premise 環境へのアクセスしなければなりません。(事実上、こんなことは不可能ですね。) さらに、サーバー側からの認証も、上記のような Azure AD ACS (Azure の STS) を使用するわけには行きません。(Azure AD ACS と On-Premise の間に、信頼関係はありません。)
On-Premise 環境の SharePoint 2013 で SharePoint Add-ins を使用する場合、実は、SharePoint-hosted と、high-trust な Provider-hosted のみがサポートされています。(つまり、Autohosted は使用できません。サポートされていない環境では、F5 による debug 実行も失敗します。)
企業内アプリケーションの場合、Web アプリケーションを企業内のネットワークに配置して App Catalog で配布するなど、配置方法についても現実的な設計が必要であり、サーバー側からの認証方法も考慮する必要があります。

 

SharePoint Server 環境の準備

環境を構築する際も、On-Premise ではいくつか面倒な設定をおこなう必要があります。(開発者にとって一番簡単なのは、Office 365 をそのまま使用することです。Office 365 では、多くの設定が、あらかじめ おこなわれています。)
以下に、これらの必要なセットアップ内容を記載します。

 

1. 必要なサービスとサービス アプリケーションの確認

まず、App で使用するサービスを確認してください。

ブラウザー (IE) を管理者権限 (run as Administrator) で開き、SharePoint 2013 Central Administration (SharePoint 2013 の全体管理画面) を表示して、[System Settings] – [Manage services on server] をクリックすると、以下の 2 つのサービスが開始されているはずです。(開始されていない場合は、これらを開始しておいてください。)

  • App Management Service (アプリ管理サービス)
  • Microsoft SharePoint Foundation Subscription Settings Service (Microsoft SharePoint Foundation 購読設定サービス)

つぎに、サービス アプリケーションを確認します。
SharePoint 2013 Central Administration を表示して、[Application Management] – [Manage service applications] をクリックします。ここで、上述した「App Management Service」と「Subscription Settings Service」のそれぞれのサービス アプリケーションと Proxy が作成されていることを確認してください。(実際、Preview 版のインストール直後のファーム作成の Wizard では、Subscription Settings Service の作成・開始はおこないませんので、このタイミングで作成・開始します。動作がおかしい場合なども作り直しましょう。)
もし、作成されていない場合は、手動で作成します。App Management Service と Subscription Settings Service のサービス アプリケーション (および、その Proxy) を作成する際は、SharePoint 2013 Management Shell (Windows PowerShell) を管理者権限で起動し、以降の通り実行します。(今回は、Managed Account を exampledemouser1 と仮定します。)

補足 : 下記を実行する前に、Managed Account (管理アカウント) が作成済みであることを確認してください。SharePoint Server 2013 Preview の Configuration Wizard 直後に表示されるファーム作成のウィザード (Start Wizard) で Managed Account の作成を促されますので、そこで作成した Managed Account を使用します。
なお、Managed Account をあとから作成する場合や、作成しなおす場合は、New-SPManagedAccount コマンドを使います。(画面が表示されるので、ドメインのユーザー ID、パスワードを指定します。)

まず、Managed Account (管理アカウント) を取得します。

$account = Get-SPManagedAccount "exampledemouser1"

つぎに、取得した Managed Account を使って、サービス アプリケーションとサービス アプリケーション プロキシを作成します。

$appPoolSubSvc = New-SPServiceApplicationPool -Name "SettingsServiceAppPool" -Account $account
$appPoolAppSvc = New-SPServiceApplicationPool -Name "AppServiceAppPool" -Account $account

$appSubscriptionService = New-SPSubscriptionSettingsServiceApplication -Name "Subscription Settings Service" -DatabaseName "SubscriptionSettingsServiceDB" -ApplicationPool $appPoolSubSvc
New-SPSubscriptionSettingsServiceApplicationProxy -ServiceApplication $appSubscriptionService

$appAppSvc = New-SPAppManagementServiceApplication -Name "Apps Management Service" -DatabaseName "AppMngServiceDB" -ApplicationPool $appPoolAppSvc
New-SPAppManagementServiceApplicationProxy -ServiceApplication $appAppSvc

 

2. App Domain (アプリケーション ドメイン) の設定

上述の通り、SharePoint-hosted の Add-ins を配置すると、SharePoint Server 内に、Add-ins 独自のドメイン (App Domain, アプリケーション ドメイン) が作成されます。このための設定を On-Premise の SharePoint でおこなうため、DNS などの設定をおこなう必要があります。

まず、DNS サーバーにログインして、DNS Manager を開きます。[Forward Lookup Zone] のドメイン名 (今回は、example.com と仮定します) を右クリックして、[New Alias (CNAME)] を選択します。表示される画面で、[Alias name] に、*.<given name> を指定し、[Fully qualified domain name (FQDN) for target host] に使用している SharePoint サイトの FQDN を設定します。

補足 : 試しに、コマンド プロンプトで下記の通り入力し、ちゃんと SharePoint サーバーのホストから応答があることを確認してみてください。
ping hogehoge.spapps.example.com

つぎに、SharePoint 2013 Central Administration (SharePoint 2013 の全体管理画面) を表示して [Apps] カテゴリーをクリックし、表示される画面で [Configure App URLs] (アプリ URL の構成) をクリックします。
表示される画面の [App domain] に、上記で設定したドメイン名 (spapps.example.com) を設定し、[App prefix] に、今回は、「sharepoint」と入力しておきましょう。(「App prefix」は、任意の文字列で構いません。)

このように設定すると、sharepoint-hosted の Add-ins の URL として、下記の形式のドメインが使用されます。(xxxxx には、アプリケーションごとの固有の文字列が設定されます。)

sharepoint-xxxxx.spapps.example.com

なお、ブラウザーでこの URL を参照できるよう、Internet Explorer の設定 (接続の設定など) も確認しておきましょう。

 

3. App Catalog (アプリ カタログ) の作成

この設定は必須ではありませんが、App Catalog (上述) を使用する場合には作成が必要です。

App catalog を作成するには、SharePoint 2013 Central Administration の [Apps] カテゴリーの中から、[Manage App Catalog] (アプリ カタログの管理) をクリックします。[Create a new app catalog site] のチェックボックスを選択して [OK] ボタンを押し、表示される画面で下図の通り設定します。
下図では、「My App Catalog」という名前で http://<server name>/sites/appcatalog に App Catalog を作成し、ドメインのすべてのユーザー (Everyone) が app catalog のアプリケーションを参照できるように設定しています。

 

SharePoint Server (On-Premises) における Add-ins の認証と注意点

SharePoint 2013 では、On-Premises (SharePoint Server 2013) の場合でも、SharePoint Add-ins 用に OAuth が使用できるようになっています。

この利用手順ですが、MSDN で Step-by-step で手順が記載されていますので、この投稿では詳細説明は省略し、以下に簡単に手順を解説したいと思います。

MSDN : How to create high-trust apps for SharePoint 2013 using the server-to-server protocol (advanced topic)
http://msdn.microsoft.com/en-us/library/fp179901.aspx#NewVersion

補足 : 上記のページには、Microsoft Office Developer Tools for Visual Studio 2012 Preview を使った開発方法と、Microsoft Office Developer Tools for Visual Studio 2012 Preview 2 を使った開発方法の 2 つが掲載されています。上記の URL (#NewVersion を含んだ URL) で、後者の手順を参照してください。

上記で記載されている手順を簡単に整理すると、下記になります。

  1. 証明書 (.pfx, .cer) を作成します。
    実際には、Windows Server などでちゃんとした証明書を発行したほうが良いですが、開発用途なら自己署名の証明書で充分です。(IIS の管理画面で作成しても良いし、makecert を使っても良いでしょう。)
  2. On-Premises の STS (Security Token Service) に Issuer と証明書 (上記で作成した public key のみの .cer) を登録します。
    On-Premises の SharePoint Server では STS のサービス アプリケーション (下図) が起動しているので、ここに Issuer を登録します。(具体的には、Windows PowerShell の New-SPTrustedSecurityTokenIssuer コマンドを実行して登録します。) ちょうど、Office 365 において、Azure Active Directory に Issuer を登録するのと同様です。
  3. Visual Studio で On-Premises 用の SharePoint Add-ins を開発します。
    この際、Provider-hosted のアプリケーションを作成します。(Visual Studio が表示するウィザードで、[Provider-hosted] を選択します。) また、Provider-hosted のプロジェクト作成のウィザードで、[Use a certificate] を選択して、上記で作成した証明書 (private key を含む .pfx) を設定します。(下図参照)
    なお、ここで設定した証明書の情報は、プロジェクトの Web.config に記述されます。下図の通り、決められたローカル フォルダなどに配置して参照することもできますし、プロジェクトに添付 (埋め込む) して参照することもできます。(実際のプロダクション コードでは、ちゃんと設計しておきましょう。)
  4. Windows Identity の情報 (ログインしている Windows Identity) からユーザー名を取り出して OAuth の Token を作成し、この Token を使って SharePoint にアクセスします。(Token を作成する際に、上記の証明書を使用します。)
    具体的には、プロジェクトに含まれる TokenHelper.GetS2SClientContextWithWindowsIdentity メソッドを使って ClientContext を取得することで、この処理が (内部で) おこなわれます。

補足 (2013/10 追記) : Visual Studio 2013 以降に含まれる新しい SharePointContext は、On-Premise に対応しました。(SharePoint Server 用に別のコードを記述する必要はありません。)

補足 : On-Premises 環境でデバッグ実行をおこなう際は、SQL Server にアクセス可能な権限を持ったユーザーで実行してください。(配置の際に、構成データベースを参照します。) また、SharePoint Server をインストールした System Account を使ったデバッグ実行は不可能です。

なお、SharePoint のサイトを Https でなく Http でホストしている場合 (たぶん、ほとんどそうですね)、既定の設定のままだと、OAuth を使った REST (CSOM) の呼び出しで 403 (Forbidden) のエラーが発生します。
MSDN : How to create high-trust apps for SharePoint 2013 using the server-to-server protocol (advanced topic)」で記載している通り、下記のスクリプト (Windows PowerShell) を実行して、Http による OAuth の利用を許可してください。

Add-PsSnapin Microsoft.SharePoint.PowerShell
$serviceConfig = Get-SPSecurityTokenServiceConfig
$serviceConfig.AllowOAuthOverHttp = $true
$serviceConfig.Update()

.NET CSOM を使ったプログラミングと認証 (Authentication)」で解説したように、Office 365 (SharePoint Online) に接続する場合は、Azure Active Directory が提供する OAuth 認証のエンドポイントを探し、Client Secret を使って、ここに OAuth の Access Token の発行を要求しました。

これに対し、On-Premises (SharePoint Server) を使った High Trust による方式では、プロジェクト (アプリ, アドイン) に設定した証明書の情報から Access Token をプログラムで生成し、これを使って SharePoint Server の REST (または CSOM) を呼び出します。(この Access Token では、「OAuth 2 Token の Decode」で紹介しているエンコード方法を使います。)
SharePoint Server 側では、On-Premises で稼働している STS (上記を参照) に登録されている公開鍵を使って、このトークンに添付されているデジタル署名の妥当性を検証し、問題なければアクセスを許可します。
なお、On-Premises に登録された Issuer は、下記の通り、Get-SPTrustedSecurityTokenIssuer で確認できます。

Add-PsSnapin Microsoft.SharePoint.PowerShell
Get-SPTrustedSecurityTokenIssuer

IsSelfIssuer : False
NameId :
RegisteredIssuerName : 58dc2ca6-e5f2-4c4b-b4bf-f5858492fcf1@d5c1ab52-1b3b-43be-aa8b-52824d40723a
IdentityClaimTypeInformation : Microsoft.SharePoint.Administration.Claims.SPTrustedClaimTypeInformation
Description :
SigningCertificate :
  [Subject]
  CN=KKDEVEVA11.example.com
  [Issuer]
  CN=KKDEVEVA11.example.com
  [Serial Number]
  2C40BEF018DC5FA2438D89565894C28F
  [Not Before]
  2012/12/10 18:35:13
  [Not After]
  2013/12/10 9:00:00
  [Thumbprint]
  341AA0BE3F97F2B3A4FB9F369A146030E829A3D1
AdditionalSigningCertificates : {}
MetadataEndPoint :
IsAutomaticallyUpdated : False
Name : 58dc2ca6-e5f2-4c4b-b4bf-f5858492fcf1
TypeName : Microsoft.SharePoint.Administration.Claims.SPTrustedSecurityTokenService
DisplayName : 58dc2ca6-e5f2-4c4b-b4bf-f5858492fcf1
Id : 7fb6b00a-7f24-40d4-a7f4-f0d73d07717f
Status : Online
Parent : SPSecurityTokenServiceManager Name=SecurityTokenServiceManager
Version : 38533
Properties : {}

なお、この手順からおわかりの通り、SharePoint Server の管理者に、あらかじめ以下の設定をお願いしておく必要があるので注意してください。(双方向の信頼に基づく Server-to-server の接続方法になります。これを high-trust と呼んでいます。)

  • Issuer (及び、証明書) の登録
  • Http を使用した OAuth 利用の許可 (Https でなく Http で SharePoint のサイトをホストする場合。既定では、Https のみが許可されています)

 

Office 365 と On-Premises の双方で動作する Add-ins の構築とデバッグ

では、本題に入りましょう。Office 365 (SharePoint Online) と On-Prem (SharePoint Server) の双方で動く SharePoint Add-ins を作成するにはどうすべきか考察します。

補足 : 「SharePoint Add-ins の動作と概要」で解説したように、SharePoint-hosted の SharePoint Add-ins の場合、そもそも Server-to-server 認証は必要ありません。(すべて JavaScript を使って構築し、かつ、ブラウザー上では認証済みの状態のため、特別な認証処理を構築する必要がないためです。) このため、SharePoint-hosted の SharePoint Add-ins は、特別な処理をしていない限り、Office 365 (SharePoint Online) と On-Premises (SharePoint Server) の双方で動作します。また、「SharePoint の Cross-domain library」で述べた手法でも、特別な認証処理は不要です。
以降では、Provider-hosted の SharePoint Add-ins で、Server-to-server 認証を使うケースを考察します。(実際、すべてを SharePoint-hosted の JavaScript のみで構築するのは非現実的だと思うので。)

上記の仕組みさえ理解していれば、Office 365 (SharePoint Online) と On-Prem (SharePoint Server) の双方で動作する Server-to-server Auth を使った SharePoint Add-ins の構築は簡単です。
要は、Office 365 か On-Prem か判断できれば、Access Token (または ClientContext そのもの) の取得方法を変えるだけです。あとは、Office 365 も On-Prem も同じように、この Access Token を使って、CSOM (ClientContext) を使ったり、Olivers さんが紹介していた REST API をサーバー サイドから呼び出せます。

On-Premises と Office 365 の Add-ins における判断方法はいくつか考えられますが、1 つ参考になるのが、「MSDN : How to create high-trust apps for SharePoint 2013 using the server-to-server protocol (advanced topic)」に記載されている下記の記述です。(抜粋します。)

In a high-trust app, there is no context token, even if you use the appredirect.aspx file. The context token is specific to configurations that use Windows Azure Access Control Service (ACS). However, an access token is still required …

つまり、下記の通り、Context Token が渡されたかどうか判断することで、Office 365 (SharePoint Online) か On-Premises (SharePoint Server) か判断できます。

. . .

protected void Page_Load(object sender, EventArgs e)
{
  Uri hostWeb = new Uri(Request.QueryString["SPHostUrl"]);
  string contextTokenString =
    TokenHelper.GetContextTokenFromRequest(Request);

  if (string.IsNullOrEmpty(contextTokenString))
  {
    // if On-Prem
    using (var clientContext = TokenHelper.GetS2SClientContextWithWindowsIdentity(
      hostWeb,
      Request.LogonUserIdentity))
    {
      . . .
    }
  }
  else
  {
    // if Office365
    using (var clientContext = TokenHelper.GetClientContextWithContextToken(
      hostWeb.ToString(),
      contextTokenString,
      Request.Url.Authority))
    {
      . . .
    }
  }

  . . .
}

また、SharePoint Add-ins の提供方法としては、Web アプリケーション (Remote App) そのものを Office 365 と On-Prem で共有する方法以外に、コードのみを共有して、On-Premises (SharePoint Server) 用に Office 365 と異なるパッケージ (.app パッケージと証明書) を提供し、On-Premises の場合には Web アプリケーション (Remote App) も含めてユーザー部門に導入してもらう方法も考えられます。(上述の通り、On-Premises の場合には、いずれにせよ、Issuer や証明書の登録などの事前設定が必要になります。) 企業によってはプロキシー設定やポリシー上の理由などから、後者のほうが現実的な場合があります。

なお、Japan SharePoint Group のデモでお見せしたように、開発時などで、Office 365 (SharePoint Online) と On-Prem (SharePoint Server) の双方で動作確認をおこなう場合、下記の方法で開発用に Publish とインストールをおこなって、双方の動作を確認できます。(Debug 用に構築された .app パッケージでは、AppManifest.xml に Client ID を自動生成するよう指定されているため、下記の方法でいったん Publish します。)
なお、SharePoint store に発行する正式なプロダクトの場合は、Seller Dashboard から Client ID、Client Secret を生成してください。下記は、あくまでも開発用の手順ですので注意してください。

  1. 証明書を使用した High-trust の Provider-hosted の SharePoint Add-ins (プロジェクト) を Visual Studio で開いて、プロジェクトの Publish をおこないます。(ローカル ディスクに .app パッケージが作成されます。)
    • Website の host 先は、IIS Express のホスト先とします (例: https://localhost:44308/ など)
    • ClientID には、任意の Guid (例: 8acb5ee0-f057-4e4c-b200-c4519e776f7c) を生成して入力し、ClientSecret は Web.config に書かれている内容 (例: 5HBVgXLJ7fVIH24DjQC/bJPQoVqpW0eXG6+pbaSOWa4=) などをコピーします。(これらは、/_layouts/15/AppRegNew.aspx のページからも発行できます。)
  2. 下記の手順で、On-Premises (SharePoint Server) 上に開発用の SharePoint Add-ins を配置します。(あらかじめ、Developer Site のテンプレートで Site を作成しておきます。)
    • http://<site url>/_layouts/15/AppRegNew.aspx を表示して、上記の App の情報 (Client Id, Client Secret など) を登録します。(登録した内容は、/_layouts/15/AppInv.aspx で確認できます。) なお、下図の [App domain] には、IIS Express の Web Application のドメイン (例: localhost:44308 など) を入力してください。
    • 上記の手順 1 で作成した <Project Name>binDebugapp.publish1.0.0.0<Project Name>.app のパッケージを [Apps in Testing] ライブラリーに Deploy します。([New app to deploy] をクリックします)
  3. Office 365 (SharePoint Online) にも、上記同様に設定します。(同様に、Developer Site のテンプレートから Site を作成しておきます。)
  4. Visual Studio のソリューションの Web プロジェクトの Web.config を開き、Client Id、Client Secret を上記の内容に書き換えます。
  5. 最後に、Visual Studio のソリューションの Web プロジェクトのみをデバッグ実行します。(ここで、SharePoint Add-ins のプロジェクトをデバッグ実行しないよう注意してください。再配置され、Client Id が書き換えられてしまいます。)

補足 : /_layouts/15/AppRegNew.aspx で登録したアプリケーションのゴミは、終わったら、ちゃんと消しましょう。「Azure Active Directory とは (事前準備)」で記載しているように、コマンドを使って削除できます。

C:WindowsSystem32WindowsPowerShellv1.0powershell.exe  -version 2.0
PS> Import-Module MSOnline
PS> Import-Module MSOnlineExtended
PS> $cr=Get-Credential
PS> Connect-MsolService -credential $cr
(rem -- id/password prompt appears. and login !)
PS> Connect-MsolService -credential $cr
PS> Get-MsolServicePrincipal -All
(rem -- check your app principals !)
PS> Remove-MsolServicePrincipal -AppPrincipalId {Guid}

 

この方法で、Office 365 (SharePoint Online) と On-Premises (SharePoint Server) の双方で、ブレーク ポイントによる停止や、ステップ実行が可能になり、テストをおこないながら、迅速に開発できます。

 

※ 変更履歴 :

2015/05/05  App for SharePoint (SharePoint 用アプリ) を SharePoint Add-ins (SharePoint アドイン) に名称変更

 

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s