2009年2月25日水曜日

ILM"2"のワークフロー概要

しばらく間が空いてしまいましたが、今回はILM"2"のワークフロー機能をひも解いて見ようと思います。

■ILM"2"の中のワークフロー機能の位置づけ

ILM"2"の中のワークフロー機能の位置づけは
・ILM Web Serviceの構成要素の一つ
・Management Policy Rule(MPR)が実行される際のプロセスの一つ
です。

















■動作の概要

ILM Web Serviceへの要求(属性の更新など)があると、あらかじめ定義されたMPRに基づいて要求は処理されます。
MPRは、要求(要求元、操作)と操作対象(対象となるリソース/SET、対象の属性)、実行されるフローの組み合わせで定義され、ILM Web Serviceへの要求がMPRに定義された要求と操作対象にマッチするとフローとILMSDBへの要求操作(CRUD)が実行されます。











■定義可能なフローの種類
ILM"2"では以下の3種類のフローを定義することができます。

種別説明
Authentication要求元を認証するために利用する(通常のパスワードで認証できないような状況/パスワードリマインドなどに利用)
Authorization要求の実行条件を満たすか確認するために利用する(承認フロー、操作対象の属性が適切かどうかの検査など)
ActionILMSDBへの操作完了後のアクションを定義する(通知する、OSRを使ってプロビジョニングを行うなど)


■フロー種別詳細
各フローには実行する動作(アクティビティ)を定義します。
・Authenticationフロー
Authenticationフローでは以下の2種類のアクティビティを利用することができます。

アクティビティ説明
Lockout GateAuthenticationフローのロックアウトを行うために利用する
QA Gate質問への回答で要求者を認証を行うために利用する


 また、各アクティビティにはそれぞれ詳細な設定を行うことができます。

アクティビティ設定項目初期値
Lockout Gateロックアウト閾値に達した後、ロックアウトされる期間(分)15
ロックアウト閾値(Authenticationフローで失敗できる回数)3
恒久的にロックアウトされるまでにロックアウト閾値に達して良い回数3
QA Gateトータルの質問の数3
事前登録時に表示される質問の数3
事前登録しなければならない質問の数3
ランダムに表示される質問の数3
正解しなければならない質問の数3
実際の質問-


・Authorizationフロー
Authorizationフローでは以下の2種類のアクティビティを利用することができます。

アクティビティ説明
Approval承認フローを定義するために利用する
Filter Validation操作対象の属性が適切かどうかをあらかじめ定義したフィルタを利用して確認する
Function Evaluatorフロー内で利用する関数を定義する
Group ValidationILM”2”のデフォルトのグループへの適合しているかを確認する
Notification特定の宛先へ通知を行う


 また、各アクティビティにはそれぞれ詳細な設定を行うことができます。

アクティビティ設定項目初期値
Approval承認者(ILMSDB上のユーザ/グループを静的に設定、もしくは要求者の属性などから動的に取得して設定)-
承認者の数1
エスカレーションタイムアウトまでの期間(日)7
メールテンプレート
・承認待ち(承認者へ送付)
・ 承認待ちのエスカレーション(承認者へ送付)
・ 承認完了(承認者へ送付)
・ 否認(要求者へ送付)
・ 要求のタイムアウト(要求者へ送付)
-
Filter Validationフィルタ対象属性を含むFilterScopeオブジェクト-
Function Evaluatorアクティビティ名-
本関数を実行した結果の値をストアする対象のオブジェクトと属性-
値として設定する属性名-
Group ValidationILM”2”のグループ管理でサポートされるプロパティを設定するかどうかを検証する(非サポートのプロパティを設定した場合はこのアクティビティは失敗する)-
ActiveDirectoryのグループ管理でサポートされるプロパティを設定するかどうかを検証する(非サポートのプロパティを設定した場合はこのアクティビティは失敗する)-
マルチフォレスト環境におけるActiveDirectoryのグループ管理でサポートされるプロパティを設定するかどうかを検証する(非サポートのプロパティを設定した場合はこのアクティビティは失敗する)-
Notification受信者(ILMSDB上のユーザ/グループを静的に設定、もしくは要求者の属性などから動的に取得して設定)-
メールテンプレート-


・Actionフロー
Actionフローでは以下の4種類のアクティビティを利用することができます。

アクティビティ説明
Function Evaluatorフロー内で利用する関数を定義する
Notification特定の宛先へ通知を行う
Password Reset Activityランダムパスワードの生成とリセットを行う
Synchronization Rule Activityあらかじめ定義したSynchronization Ruleを実行する(プロビジョニング/デプロビジョニング/属性毎に動作を変更)


 また、各アクティビティにはそれぞれ詳細な設定を行うことができます。

アクティビティ設定項目初期値
Function Evaluatorアクティビティ名-
本関数を実行した結果の値をストアする対象のオブジェクトと属性-
値として設定する属性名-
Notification受信者(ILMSDB上のユーザ/グループを静的に設定、もしくは要求者の属性などから動的に取得して設定)-
メールテンプレート-
Password Reset Activity生成するパスワードの文字列長10
Synchronization Rule Activity実行するSynchronization Rule-
Synchronization Ruleの対象の中で実行するアクション(プロビジョニング/デプロビジョニング/属性毎に動作を変更)-


次回は実際に承認フローを設定する手順を解説したいと思います。



2009年2月17日火曜日

MVRouterアーキテクチャ



引き続きILM(というかMIIS)の話題です。
なぜ今さら、という話もあるんですがILM"2"も結局はHybridな構造なので、レガシーな作り込みはおそらくなくならないだろうな~、と思っているからです。
ライセンス的にもILM"2"の画面系を使わなければCAL不要?みたいな話もありそうなので、管理者だけがWSS上でアカウントを管理して実ユーザにセルフサービスはさせないという使い方も実際はあり得そうですし。

さて、MIIS/ILMの最大の欠点は何か?と言われたら、Metaverseのrules extensionが実質ひとつのDLLに閉じられてしまっていて、分散開発やメンテナンスがとってもしにくい、という点があげられると思います。
MIISのDeveloperリファレンスにも載っているので、実際に商用環境で使っている方はこの方法を使っているのかな?とは思いますが、その名も「MVRouter」です。

やっていることは単純で、親DLLから各ターゲット用に用意したextension用DLLを呼び出しているだけですが、これでずいぶんメンテナンスは楽になるのかと思います。
















具体的には下記のようなコードを書きます。

■親DLL(MVExtention.dll)

Imports Microsoft.MetadirectoryServices
Imports System.IO
Imports System.Reflection

Public Class MVExtensionObject
  Implements IMVSynchronization

  ' 変数定義
  Dim arrMVDlls() As IMVSynchronization

  Public Sub Initialize() Implements IMvSynchronization.Initialize
    ' MVExtensionファイル名の取得の読み込み
    Dim arrDllNames() As String = Directory.GetFiles(Utils.ExtensionsDirectory, "MV_Ext_" & "*.dll")
    Dim numDlls As Integer = arrDllNames.Length - 1
    ReDim arrMVDlls(numDlls)
    Dim iCnt As Integer
    Dim strFileName As String
    Dim Assem As [Assembly]
    Dim type, types() As Type
    Dim objLoaded As Object
    Dim isLoaded As Boolean

    ' MVExtentionライブラリのロード
    For iCnt = 0 To numDlls
      strFileName = arrDllNames(iCnt)
      Assem = [Assembly].LoadFrom(strFileName)
      types = Assem.GetExportedTypes()

      ' MVExtentionライブラリであることを確認
      isLoaded = False
      For Each type In types
        If (Not (type.GetInterface("Microsoft.MetadirectoryServices.IMVSynchronization") Is Nothing)) Then
          ' オブジェクトインスタンスの生成
          objLoaded = Assem.CreateInstance(type.FullName)
          isLoaded = True
          Exit For
        End If
      Next

      If isLoaded = True Then
        ' ロードしたライブラリを変数へ代入
        arrMVDlls(iCnt) = objLoaded
        ' ライブラリの初期化
        arrMVDlls(iCnt).Initialize()
      Else
        ' ロード対象ライブラリが存在しなかったら例外処理
        Throw New UnexpectedDataException("MVExtensionライブラリが見つかりません")
      End If

    Next
  End Sub

  Public Sub Terminate() Implements IMvSynchronization.Terminate
    Dim objDll As IMVSynchronization
    ' ロードされたライブラリの終了処理
    For Each objDll In arrMVDlls
      objDll.Terminate()
    Next
  End Sub

  Public Sub Provision(ByVal mventry As MVEntry) Implements IMVSynchronization.Provision
    Dim objDll As IMVSynchronization
    ' 各ライブラリのProvisioning実行
    For Each objDll In arrMVDlls
      objDll.Provision(mventry)
    Next
  End Sub

  Public Function ShouldDeleteFromMV(ByVal csentry As CSEntry, ByVal mventry As MVEntry) As Boolean Implements IMVSynchronization.ShouldDeleteFromMV
    Dim objDll As IMVSynchronization
    Dim shouldDelete As Boolean = False

    ' 各ライブラリのShouldDeleteFromMV実行
    For Each objDll In arrMVDlls
      If objDll.ShouldDeleteFromMV(csentry, mventry) Then
        shouldDelete = True
        Exit For
      End If
    Next

    ShouldDeleteFromMV = shouldDelete
  End Function

End Class




■子DLL(MV_Ext_AD.dll)
Imports Microsoft.MetadirectoryServices

Public Class MVExtensionObject
  Implements IMVSynchronization

  Public Sub Initialize() Implements IMvSynchronization.Initialize
    ' TODO: Add initialization code here
  End Sub

  Public Sub Terminate() Implements IMvSynchronization.Terminate
    ' TODO: Add termination code here
  End Sub

  Public Sub Provision(ByVal mventry As MVEntry) Implements IMVSynchronization.Provision
    Select Case mventry.ObjectType
      Case "person"
        Dim conMA As ConnectedMA = mventry.ConnectedMAs("MA_AD")
        Dim strCN As String = mventry("employeeID").Value.ToString
        Dim strRDN As String = "CN=" & strCN
        Dim refDN As ReferenceValue = conMA.EscapeDNComponent(strRDN).Concat
("ou=users,ou=ilm2007objects,dc=ilm,dc=local")
        Dim numConns As Integer
        Dim csentry As CSEntry

        numConns = conMA.Connectors.Count
        If numConns = 0 Then
          ' 新規エントリ→作成
          csentry = conMA.Connectors.StartNewConnector("user")
          csentry.DN = refDN
          csentry("unicodePwd").Values.Add("P@ssw0rd")
          csentry.CommitNewConnector()
        ElseIf numConns = 1 Then
          ' 既存エントリ
          csentry = conMA.Connectors.ByIndex(0)
          csentry.DN = refDN
        Else
          ' 例外
          Throw New UnexpectedDataException("MAに複数のコネクタオブジェクトが存在します")
        End If
      Case Else
    End Select
  End Sub

  Public Function ShouldDeleteFromMV(ByVal csentry As CSEntry, ByVal mventry As MVEntry) As Boolean Implements IMVSynchronization.ShouldDeleteFromMV
  End Function
End Class



最近はもう少しスマートに実装するようで、MAとExtensionDLLの名前をXMLファイルで定義して、MVExtension.dllから構成情報を読み出してロードする、という方法もとられているようです。

ILM"2"が出てきたらISR/OSRとの合わせ技のベストプラクティスが出てくるのかな?とは思っています。

2009年2月10日火曜日

退職そして復職(ILM2007で実装してみました)



実際にあった要件で、
①人事システムからはアクティブ(在籍中の)ユーザ一覧のみしか渡せない
②非アクティブユーザのActiveDirectory上のエントリを無効化したい
③一度退職した人も復帰するケースがあるので、その際はActiveDirectory上のエントリを再度有効化してほしい(結構偉い人の場合が多いので新規IDで、というわけにはいかないらしい・・・)
という話がありました。

話を聞くだけだと「ふ~ん、なるほど」という話なんですが、実装をしてみるとそれなりに面倒です。

よくWeb上などで出回っている情報だと、人事システム側にEmployeeStatusのような状態を示す属性があり、その属性を基にActiveDirectoryのuserAccountControlを変更して、、、というようになっています。

ただ、冒頭に挙げた例も含め実際の要件ってそんなにIdMに都合のよいインプット情報が渡ってくるわけではないので、今回の様に工夫が必要になります。

まず①ですが、要するに入社するとエントリが増え、異動するとエントリの属性が変更され、退職するとエントリが消えるということになります。(下表)


入力情報の例
元情報id,sn-j,givenName-j,sn-e,givenName-e,Department
0001,田中,一郎,Tanaka,Ichiro,営業部
入社時id,sn-j,givenName-j,sn-e,givenName-e,Department
0001,田中,一郎,Tanaka,Ichiro,営業部
0002,佐藤,次郎,Sato,Jiro,開発部
異動時id,sn-j,givenName-j,sn-e,givenName-e,Department
0001,田中,一郎,Tanaka,Ichiro,営業部
0002,佐藤,次郎,Sato,Jiro,営業部
退職時id,sn-j,givenName-j,sn-e,givenName-e,Department
0001,田中,一郎,Tanaka,Ichiro,営業部


次に②ですが、これは普通に考えるとActiveDirectory用のMA(以下MA_AD)のDeprovisioning Optionにrules extensionを書いて、その中でcsentryのuserAccountControlに無効値(ADS_UF_ACCOUNTDISABLE)をセットしてあげれば問題ないんですが、今回は最後③の復帰を考えてあげないといけません。

通常のProvisioningの動きだと、MetaVerse(以下MV)と対象のConnectorSpace(以下CS)のオブジェクト間にリンクがあるかどうかによってオブジェクト(csentry)の新規作成をするか、既存エントリの更新を行うかが決定されます。
ただし今回普通にdeprovisionを使ってしまうと、MVとMA_ADのCS内オブジェクト間のリンクが切断されてしまいますし(※)、そもそもdeprovisionはMVのオブジェクトが削除されないと走らない、という制限があります。

※deprovision関数の返却値はDeprovisionActionという型で、選択肢として、
 ・DeprovisionAction.Delete → CSからの削除(AD上にオブジェクトは残したいので今回使えない)
 ・DeprovisionAction.Disconnect → 再接続可能な状態でdisconnectする
 ・DeprovisionAction.ExplicitDisconnect → 再接続不可能な状態でdisconnectする
 しか存在しません。





















この状態で再度provisioningを実行すると、MVとCSのリンクがないので新規作成という動作が選択されるのですが同じDNのcsentryは消えずにCS上に残っているので「Already Exist」という形でエラーが出てしまいます。

















これを回避するために、
・人事システム用MA(MA_HR_PERSON)のCSとMVの間のリンク状況を見てAD_MAのCS内オブジェクトの属性(userAccountControl)をコントロールする
ということをしてみます。(当然他にも方法はあると思います)

具体的には、AD_MAのAttribute Flowのrules extensionを使います。
この中で、対象のmventryがMA_HR_PERSONのCSとリンクがあるかどうかを、
 mventry.ConnectedMAs("MA_HR_PERSON").Connectors.Count
に入っている値を見ることで判断します。
値が0ならリンクはありませんし、1ならリンクされているオブジェクトがある、と判断できます。

実際のコードはこんな感じです。

Public Sub MapAttributesForExport(ByVal FlowRuleName As String, ByVal mventry As MVEntry, ByVal csentry As CSEntry) Implements IMASynchronization.MapAttributesForExport

 Const ADS_UF_ACCOUNTDISABLE As Long = &H2 ' Disable user account
 Const ADS_UF_NORMAL_ACCOUNT As Long = &H200 ' Typical user account
 Dim currentValue As Long

 Select Case FlowRuleName
  Case "cd.user:userAccountControl<-mv.person:"
   If csentry("userAccountControl").IsPresent Then
    currentValue = csentry("userAccountControl").IntegerValue
   Else
    currentValue = ADS_UF_NORMAL_ACCOUNT
   End If
   If mventry.ConnectedMAs("MA_HR_PERSON").Connectors.Count = 0 Then
    'HR_MAに存在しない→無効化
    csentry("userAccountControl").IntegerValue = currentValue Or ADS_UF_ACCOUNTDISABLE
   Else
    'HRに存在する→有効化
     csentry("userAccountControl").IntegerValue = (currentValue Or ADS_UF_NORMAL_ACCOUNT) And (Not ADS_UF_ACCOUNTDISABLE)
   End If
  Case Else
   Throw New EntryPointNotImplementedException()
 End Select
End Sub

以下、実際に実行した結果です。

■通常同期







CSVファイルの中身





















MA_HR_PERSONのfull import & full syncの結果















MA_ADのexportの結果















ADのオブジェクト状態


■退職







CSVファイルの中身





















MA_HR_PERSONのfull import & full syncの結果














MA_ADのexportの結果















ADのオブジェクト状態


■復職







CSVファイルの中身





















MA_HR_PERSONのfull import & full syncの結果














MA_ADのexportの結果














ADのオブジェクト状態


2009年2月7日土曜日

Webinar:The Business Impact of Identity Management with ILM"2"

さて、一週間間が空いてしまいましたが今週もensynchのWebinarに参加しました。

今回のテーマは前回書いたとおり、「The Business Impact of Identity Management with ILM"2"」でした。
今回は参加者数が35人程度と前回より少なめでした。















アジェンダは以下の通り。

・Intro to Ensynch
・Business Challenges vs. Technical Challenges
・Technical Issues that Identity Management Solves
・Business Benefits
・Estimate Cost and Savings/Gains
・ROI Opportunity
・QA


今回は特にILM"2"に特化した話ではなく一般論としてのビジネス上の課題と、それをIdMがどのように解決するのか、という話が中心でしたのでありふれた話ではありました。
話の中で紹介されていたのが、多少こじつけ感もありますが、以下のような内容です。

ビジネス上の課題 根本となるビジネス上の問題 原因 技術的な原因
ビジネスの立ち上がりが遅れる 従業員が受け取っていてしかるべきコミュニケーションができない eMailアカウントを持っていない
適切なメーリングリストに入っていない
メーリングリストの自動化ができていない
従業員が顧客要求を実現できない 従業員がしかるべきリソースへアクセス権限を持っていない 必要なシステムへアカウントがプロビジョニングされていない
必要なグループやロールのメンバになっていない
従業員がパスワードを忘れてしまった
グループやロールの自動管理ができていない
パスワードリセット機能が存在しない
顧客情報や株価に影響する情報の漏えいや価値のある情報の破壊が起きる 従業員がアクセスできるべきでないリソースへアクセスできてしまう
退職後の社員がリソースへのアクセス権限を保持し続けている
パーミッションが緩い
ユーザアカウントが削除されていない
グループの自動管理ができていない
自働デプロビジョニングができていない
アテステーション機能がない
従業員が顧客の問題をエスカレーションする適切な相手を見つけられない 従業員が互いに正確で最新のコンタクト先情報を見つけられない 全社アドレス帳やデータベースが同期されていない IDAツールで同期されないディレクトリが乱立している




この手の話は非常にありふれている上にかなりこじつけ(必要条件かもしれないが十分条件ではない)ので、USのユーザはどのように感じたのか微妙な感じです。

結局この話の後はCALの半額キャンペーンの話があったり、サーバライセンスが$1という超特価の案内があって、そのまま話は終わって行きました。。。。
















今後のWebinarですが、
2/25:Workflow関連
来月:Business Impact of Geneva
といった予定だそうです。

個人的にはマイクロソフトのクラウドでのビジネスモデルが気になるので、Genevaの話を是非聞いてみたいと思います。また面白かったらレポートします。