Posts for: #Microsoft Entra Id

増上寺の東京タワー

増上寺の東京タワー

今日の運動は縄跳び(両足跳),散歩,ハンドグリップをした。統計を 運動の記録 にまとめる。

msgraph-sdk-go のデバッグ

me-id の調査 を経て msgraph-sdk-go の delta クエリを使って変更差分を取得できるようになった。デバッグしていて、プロパティの値を変更したときに差分を取得できているものの、変更する値を空の値にする (null) にしたときの変更を検知できていないことに気付いた。実際のレスポンスは null が連携されているものの、sdk 側のコードで null を無視しているようにみえた。おそらく sdk のバグなんじゃないかと思って discussion ではなく issue として登録してみた。

もしかしたら他の api で代替できるのかもしれないけれど、そうじゃなかったら、これは致命的な不具合だと思う。こんな実運用で使ったらすぐ気付く不具合がこれまでに修正されていないとしたら go の sdk で delta クエリの運用を誰もやっていないの?とか思ってしまう。

スーパーホテル

今日から スーパーホテル 東京・芝 に2泊する。スーパーホテルというホテルチェーンがあることは知っていたけれど、実際に泊まるのは初めてだった。避けていたわけではないのにこれまで機会がなかった。泊まってみてとてもよかった。施設・設備は整っているし、大浴場ではないけど個室よりは広いお風呂があるし、朝食も無料でついてきて、その上に宿泊料金が安い。コスパという視点では、いつも宿泊している京王プレッソインよりも高いと思う。他の場所のスーパーホテルにも泊まってみようという気持ちにさせるぐらいの、今回の宿泊体験はよかった。

しばの上の運動

今日もお仕事を終えてから散歩に出掛けた。芝公園 や増上寺の付近をぐるぐるまわりながら縄跳びができそうな場所を探していた。芝生の広場もあったけれど、早い時間帯は人がたくさんいて、縄跳びすると変な人にみられそうだったので、弁天池という人気のないところで縄跳びをしていた。22時頃に芝生の広場の前を通ったらかなり人が減っていたので遅い時間帯ならここでもよいかもしれない。20代後半のときにこの付近に住んでいたので増上寺や東京タワーを眺めるのも懐かしかった。出張したときの運動するコースとして芝公園周りはちょうどよいと思う。

2024年度の変更登記第一弾

今日の運動は腹筋ローラー,背筋,縄跳び(両足跳),散歩,ジョギング,ハンドグリップ,ダンベルをした。統計を 運動の記録 にまとめる。

変更登記の申請1

昨日 資本金の入金 を行ったので変更登記を申請する。法律では変更後2週間以内に申請しないといけない。9時過ぎに法務局へ行って申請した。オフィスから徒歩10分以内に法務局があるので気軽に行ける。

申請書を提出する手順は次になる。滅多に行かないからいつも忘れてしまっているが。

  1. 登録免許税の金額分の収入印紙を購入する
  2. 申請書の台紙に収入印紙を貼り付ける
  3. 法人登記専用受付へ行って申請書を提出する
  4. 受付スタッフが簡単に書類チェックして不備がなければ受付となる
    • 書類の内容は後日に別途審査される

4営業日以内に法務局から連絡がなければ変更登記は完了しているとみなせる。問題があれば提出して翌日か翌々日ぐらいには電話がかかってくる。

me-id 調査

選手からの me-id の調査の続き 。Microsoft Graph API の delta query という仕組みで entra id のユーザー/グループ情報に変更があったときにその差分を検出できる。ドキュメントはおそらく次の2つを参照すればよいはず。

もっとも API としての設計が開発者にとって直感的なものではないから、自分で動かしてデバッグしないとドキュメントだけで振る舞いを理解するのは至難だと思う。msgraph-sdk-go を使ったアプリケーションのデバッグをしていたときも実感したけど、azure のプラットフォームとしての品質は低い。ドキュメントがたまに間違っているし、仕様も振る舞いも論理的に説明がつかないこともある。開発者がちょっと触っただけで気付くというのは中身の品質はもっと低いと推測される。google や amazon の方が品質が高い。

実際に sdk を使って entra id のユーザーやグループの変更を行いながら、リクエストしてデバッグしてわかったことを書く。

  • nextLink と deltaLink は排他的な関係にある
    • nextLink が返される場合は、実際に差分データがなかったとしてもそのセッション内で次のデータがあることを意図している。nextLink が返され続けている限り、その情報を使ってリクエストし続ける必要がある。実際にはなにもデータが取得されないということもある。基本的には変更がなければ1回で終わるが、数十回ぐらいリクエストし続ける場合もある
    • deltaLink は rdbms でいうところの cursor のような概念になる。ldap プロトコルで言うところの cookie に相当する。その時点以降の差分のみを取得するためのトークンになる。deltaLink を使ったリクエストのときに新しい変更の差分情報を取得できる
    • 毎秒リクエストするような頻繁なリクエストだと、同じ変更差分を複数回取得することがある (at least once)
      • 30秒ごとに取得するようにしたら再現しなかったのでデータストアが eventual consistency な振る舞いをしている
  • 削除やメンバーの差分のような情報は sdk の api では additional data と呼ばれる領域に map で格納されている
    • ドキュメントではこれらをアノテーションと呼んでいた気がする
  • 削除は @removed というデータが含まれる
{
  "@removed": {"reason": "changed"}
}
  • メンバーの変更は members@delta というデータに含まれる
    • ユーザーとグループの関係を表すようなものは propertyName@delta というフィールドで additional data に含まれる
{
  "members@delta": [
    {
      "@odata.type": "#microsoft.graph.user",
      "id": "693acd06-2877-4339-8ade-b704261fe7a0"
    },
    {
      "@odata.type": "#microsoft.graph.user",
      "id": "49320844-be99-4164-8167-87ff5d047ace"
    }
  ]
}

たとえば、グループの変更とグループメンバーの変更を検出するには次のようなコードになる。これは振る舞いを検証するためのデバッグのために書いた検証コードなので実際のアプリケーションに使うようなものではない。

func groups() {
	defaultOptions := &azidentity.ClientSecretCredentialOptions{
		ClientOptions: azcore.ClientOptions{
			Retry: policy.RetryOptions{
				MaxRetries:    3,
				TryTimeout:    10 * time.Second,
				RetryDelay:    20 * time.Second,
				MaxRetryDelay: 80 * time.Second,
			},
		},
	}
	credential, err := azidentity.NewClientSecretCredential(
		tenantID, clientID, secret, defaultOptions,
	)
	if err != nil {
		log.Fatal(err)
	}
	client, err := msgraphsdk.NewGraphServiceClientWithCredentials(
		credential, defaultScopes,
	)
	if err != nil {
		log.Fatal(err)
	}

	ctx := context.Background()
	headers := abstractions.NewRequestHeaders()
	headers.Add("Prefer", "return=minimal")
	conf := &graphgroups.DeltaRequestBuilderGetRequestConfiguration{
		Headers: headers,
	}

	delta, err := client.Groups().Delta().GetAsDeltaGetResponse(ctx, conf)
	if err != nil {
		log.Fatal(err)
	}

	i := 0
	for {
		fmt.Println(i)

		fmt.Println("delta AdditionalData")
		ad := delta.GetAdditionalData()
		for k, v := range ad {
			if k == "@odata.context" {
				if s, ok := v.(*string); ok {
					fmt.Printf("%+v: %+v\n", k, *s)
				}
			} else {
				fmt.Printf("%+v: %+v\n", k, v)
			}
		}
		fmt.Println("------------------------")

		for _, d := range delta.GetValue() {
			fmt.Println("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^")
			id := d.GetId()
			if id != nil {
				fmt.Printf("id: %+v\n", *id)
			}

			fmt.Println("group AdditionalData")
			dad := d.GetAdditionalData()
			for k, v := range dad {
				if k == "@removed" {
					removed := v
					if removed != nil {
						for k, v := range removed.(map[string]any) {
							if reason, ok := v.(*string); ok {
								fmt.Printf("%+v: %+v\n", k, *reason)
							}
						}
						fmt.Println("------------------------")
					}
				} else if k == "members@delta" {
					fmt.Println("members@delta")
					ms := v.([]any)
					for _, mi := range ms {
						m := mi.(map[string]any)
						for k, v := range m {
							switch vv := v.(type) {
							case *string:
								fmt.Printf(" - %+v: %+v\n", k, *vv)
							case map[string]any:
								fmt.Printf(" - %+v: %+v\n", k, vv)
							}
						}
						fmt.Println("---------")
					}
				} else {
					fmt.Printf("%+v: %+v\n", k, v)
				}
			}
			dispName := d.GetDisplayName()
			if dispName != nil {
				fmt.Printf("dispName: %+v\n", *dispName)
			}
		}

		nextLink := delta.GetOdataNextLink()
		deltaLink := delta.GetOdataDeltaLink()
		if deltaLink != nil {
			fmt.Printf("hasNextLink: %t, use deltaLink to request\n", nextLink != nil)
			delta, err = client.Groups().Delta().WithUrl(*deltaLink).Get(ctx, conf)
			if err != nil {
				log.Fatal(err)
			}
			i++
			<-time.After(10 * time.Second)
			continue
		}

		delta, err = client.Groups().Delta().WithUrl(*nextLink).Get(ctx, conf)
		if err != nil {
			log.Fatal(err)
		}

		<-time.After(1 * time.Second)
		i++
	}
}

みなとのもりの運動

前回の所感 。いつも通りのメニューをこなす。19時頃に公園へ通うのも習慣になりつつある。今日もよい場所を陣取ったものの、後からフライングディスクのサークルの人たちが近くに来て練習を始めた。他が空いているのだからもう少し余裕をもって場所をとってくれたらよいのに、微妙に視界に入って気になる距離感のところで練習を始める。接触するわけではないから問題はないのだけど、フライングディスクというスポーツの特性上、ディスクが飛んできたら走ってくるから十分に離れていないと、たまたまディスクがそれたときに危なくないかが気になってしまう。だいたいストレッチと縄跳びとジョギングと筋トレとストレッチでだいたい1時間ぐらいかかる。だいぶ慣れてきたので、負荷を増やすためにもう少しメニューを追加してもよい時期かもしれない。

淡々と週明け

今日の運動は腹筋ローラー,背筋,縄跳び(駆け足跳),ジョギング,ハンドグリップ,ダンベルをした。統計を 運動の記録 にまとめる。

me-id 調査

先週から me-id の調査 をずっとやっている。ちょうど明日にチームの定例会議があるので、現時点で調査した内容を整理してメンバーに共有するために資料を作ってみた。運用におけるシステム構成として考えられるパターンがいくつかあって、それらにすべて対応するのか、一部の用途だけに対応するのか、そういった要件の取捨選択や優先度も決めないといけないことがわかってきた。me-id が柔軟なシステム構成をとれるよう設計されているため、私が想定していたよりもちゃんと対応するのは大変なのかもしれない。調査内容の共有のためにスライドを作ったら20枚ほどになった。システム構成を議論するための資料が20枚になってしまうぐらいの、me-id の複雑さ、もしくは柔軟さが伺える。

みなとのもりの運動

前回の所感 。昨日は雨降りでお休みしていた。今朝はよい天気で気持ちよかったので今日からまた再開しようと、カレンダーに月-金まで公園運動の予定を入れた。予定を入れて運動部のチャンネルにコメントした。それで後にひけなくなって運動することへのモチベーションや勢いになる。今日も縄跳びしてから軽くジョギングも入れてみた。土曜日よりは足の疲労が残っていたから控えめにした。あと周りが暗くなるとジョギングしていても寂しい気持ちになるから昼間の方が走るモチベーションになる気はした。

運動のためのグッズを運ぶバッグを買ってみた。ダンベルとか重いので、ちょっと大きめの、帆布で頑丈なバッグにしてみた。普通のトートバッグだと紐が切れないか心配だったのでこれは頑丈そうで満足。

entra id のエンタープライズアプリケーションの正体

今日の運動は腹筋ローラー,縄跳び(両足跳),散歩,ジョギング,ハンドグリップをした。統計を 運動の記録 にまとめる。

me-id 調査

昨日の続き。システム構成をどうするか分かってきた。entra id に対するエンドポイントは基本的には Microsoft Graph API になる。これとは別に、自動プロビジョニングするには、entra id から scim 2.0 のプロトコルを用いてサードパーティサーバーに対してリクエストが送られる。entra id のエンタープライズアプリケーションという設定項目に google だったり slack だったりといったサードパーティのクラウド向けのアプリケーションが登録されている。それらが何をしているかというと、entra id から自動プロビジョニングによってリクエストされる scim 2.0 のエンドポイントの設定を提供している。そのエンタープライズアプリケーションにそれぞれのサードパーティサービスのエンドポイントの uri や credentials を設定する。entra id からリクエストを受け取って多少の加工などもしているかもしれない。

そこまで理解できたときにちょうどチーム勉強会があったので調査内容の中間報告のようなことをしていたら、オンプレミス AD にプロビジョニングするエンタープライズアプリケーションは microsoft 社が提供している。azure 上に windows サーバーを構築してオンプレミス AD を設定して自動プロビジョニングしたら、既存の agent から dirsync で id 連携できるんじゃないか?というコメントがあって、確かにその方がネットワークも考慮したシステム構成として理にかなっているし、うちらの開発コストが減って、すでに運用で使われている他社のアプリケーションも再利用できてよいかもしれないと思えてきた。明日はその検証をやってみる。

みなとのもりの運動

前回の所感 。オフィスから出掛けるすこし前に夕立が降ったらしく路面が濡れていた。天気予報をみたら降水確率は0%だったので一時的にざざーっと降ったようにみえる。この状態だと公園の芝生の上で縄跳びすると靴がずぶ濡れになるのでコンクリートの乾いているところの上で縄跳びをした。ひざに負担はかかるけど、コンクリート面の方が回数はたくさん跳べる。土の地面よりもコンクリート面の方が体力の消費も少ない。したがって休憩を挟まずに長く跳び続けられる。とはいえ、コンクリート面の縄跳びはひざへの負担が気になるから、今日は駆け足跳びをやめてジョギングしてみた。公園のトラック1周は約500mある。すこし前にジョギングできた ことから体重が減って股関節への負担が減ってジョギングも軽くならやってもよさそうな雰囲気が出てきた。休みながら2.5周走ってみた。

今週は me-id 調査と scim client のサンプル実装

今日の運動は腕立て,縄跳び(両足跳,駆け足跳),散歩,ハンドグリップ,ダンベルをした。統計を 運動の記録 にまとめる。

me-id 調査

今週から Microsoft Entra ID (省略名は me-id) の調査をしている。ドキュメントはたくさんあるものの、機能や提供形態が多いために私がやりたいことを説明しているドキュメントがどこにあるのかを探すのが面倒だった。me-id から id 連携をするためのプロビジョニングを自分たちで実装したい。どうやらその説明のドキュメントは次のようにみえる。

me-id としては sicm でプロビジョニングを行う api を提供していて、watermark と呼ばれる、rdbms で言うところの cursor のような仕組みで更新差分を取得する仕組みを提供している。scim client は microsoft 社も提供しているが、クローズドソースで windows 向けアプリケーションしか提供されていないため、自前で scim client を実装する必要があるということを月・火の2日間かかって理解できてきたといった進捗。なかなか難しい。

駐車場の契約

昨日の続き 。昨日の夜にオンラインで申し込みしたものの、いくつかフォームの記載事項に訂正を求めるメールが届いた。修正した内容を返信して数時間で審査を完了したから契約書を締結する連絡が届いた。普通に拒否されるわけはないのだけど、1度マンションのオーナー審査で拒否されてから法人契約の審査はわりとどきどきする。そして審査に落ちるとヘコむ。契約書や車庫証明関連の書類などは後日、郵送されることにはなるが、丸1日経たない時間で駐車場の契約自体はできてしまった。効率がよい。

みなとのもりの運動

前回の所感 。運動部のチャンネルにこの火曜日から木曜日までは 18:30 - 19:30 に公園へ行くと宣言して通うようにしている。こうやって公けに言ってしまうと引けなくなるので無理やりでも行くようになる。今日は18時半に雑用していたら出掛けるのが19時半になった。遅い時間に公園へ行った分、スペースは空いていた。いつも通り、シートを広げて場所取りしてストレッチをしていた。すると、短距離走のチームが近くに来て、ややパーソナルスペースに引っかかるといった所感をもった。向こうのチームもシートを広げてストレッチをしていた。同じようなことを考える人たちもいるもんや。今日は普通にストレッチして、縄跳びして、歩いてきて、ストレッチして、筋トレして、といつも通りのメニューをゆっくりこなしてきて満足した。