この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので十分ご注意ください。
背景
以前、以下の理由でSAML認証方式でAmazon Grafana ログインの ID プロバイダー (IDP) として構成の手順を検証したので、備忘録として残したいと思います。
Amazon Managed Grafana の認証認可には以下の方式があるが、権限がないので AWS IAM Identity Center を構成できない
AWS IAM Identity Center (旧 SSO)
任意の SAML IdP
なお執筆時点では、次の外部IDプロバイダーのSAML認証がAmazonManaged Grafanaでテストされているようです。
Azure Active Directory
CyberArk
Okta
OneLogin
Ping Identity
それぞれのIDプロバイダーでの設定方法は下記を参考にして頂ければと思います。
https://docs.aws.amazon.com/ja_jp/grafana/latest/userguide/authentication-in-AMG-SAML.html
前提条件
・検証用EC2(AMI名:Windows_Server-2019-Japanese-Full-Base-2023.03.15)が構築済みであること
・AWS Microsoft Managed ADが構築済みであること
・Windowsファイアウォールが無効に変更済みであること
・通信制御はセキュリティグループで実施済みであること
・サーバーでの作業は Admin ユーザーで実施すること
SAMLとは
SAMLとは、Security Assertion Markup Languageの頭文字を取ったもので「サムル」と読み、SSO(シングルサインオン)やID連携などで利用される、マークアップ言語を中心とする認証情報の規格のことです。
SSOを実現する仕組みの一つで、異なるインターネットドメインの間でユーザーの認証情報をやり取りする際に使われます。
SPを起点とした場合のフロー
まず、ユーザーが使いたいサービス(サービスプロバイダ:SP)にアクセスすると、SPではユーザーが利用を許可されているアカウントかどうかを確認(認証リクエスト)します。
これを受けて、ユーザーは、SAML認証を提供するIdP(Identity Provider)に認証依頼を行い、入力したID/パスワードが正しいと判断されれば、認証トークンを発行してもらいます。
ユーザーは、IdPに発行してもらった認証トークンをSPに渡します。
すると、SPは認証トークンを確認して正規のユーザーであれば認証するという仕組みです。
IdPを起点とする場合
IdPを起点とした場合は、まず、ユーザーがIdPにアクセスして、認証依頼を行います。
ここで入力したID/パスワードが正しいものなら、認証トークンが発行されます。
次に、ユーザーは利用したいサービス(SP)にアクセスします。
すると、SPはIdPから発行された認証トークンを検証し、正規のユーザーであると判断されれば、認証します。
構成図
手順
1.ADFS サーバーのドメイン参加
1.コンピューター名変更
コンピューター名を「ADFS1」に変更し、再起動します。
2.DNSアドレスの設定
作成した EC2 インスタンスをドメインに参加させるために TCP/IPv4 のプロパティにて、Managed Microsoft AD の DNS アドレスを参照して設定します。
3.ドメイン参加
Managed Microsoft AD にて設定したアカウント情報を入力します。(ユーザー名は、Admin@ads.cjbiz.info と名前@ドメイン名 の形式となります。)
ドメインに参加させるとコンピューターの再起動をするか聞かれるのでそのまま再起動します。
4.Active Directory の管理に必要なツールをインストールします。
ドメインユーザでログインします。(Admin@ads.cjbiz.info )
Active Directory の管理に必要なツールをインストールします。
「機能」の選択画面で、少し下へスクロールして「グループポリシーの管理」にチェックを入れます。
2.ADFS の構築
1.gMSAの作成
New-ADServiceAccount -Name ‘adfs-service’ –DNSHostName ‘adfs1’
2.証明書の準備
証明書を作成します。
$params = @{
Subject = '*.cjbiz.info'
DnsName = '*.cjbiz.info'
CertStoreLocation = 'cert:\LocalMachine\My'
KeyAlgorithm = 'RSA'
KeyLength = 2048
KeyExportPolicy = 'Exportable'
NotAfter = (Get-Date).AddYears(5)
}
$cert = New-SelfSignedCertificate @params
$cert
# ADFSおよびクライアント用にエクスポートしておく (要管理者権限)
# ※エクスポート先およびパスワードは適当なので適宜変更してください
mkdir C:\Temp
Export-PfxCertificate -Cert $cert -FilePath "C:\temp\adfs.pfx" -Password (ConvertTo-SecureString "P@ssw0rd" -AsPlainText -Force)
証明書をインポートします。
# 証明書情報を Powershell より取得します。
Get-ChildItem Cert:\LocalMachine\My\
3.ADFS コンテナーの作成
以下の関数を Powershell で実行して、[ドメイン名]/[NetBIOSドメイン名]/ 配下に ADFS とランダムな GUID のコンテナーを作成し、その設定情報を $adminConfig 変数に格納していきます。
# gMSA専用関数
function New-NonDADkmContainerForgMSA {
[CmdletBinding()]
param (
[Parameter(Mandatory=$True)]
[string]$AcctToAclDkmContainer
)
$userNameSplit = $AcctToAclDkmContainer.Split("\")
if ($userNameSplit.Length -ne 2)
{
Write-error "Specify non-DA local admin user in 'domain\username' format"
return $false
}
# The OU Name is a randomly generated Guid
[string]$guid = (New-Guid).Guid
Write-Host ("OU Name" + $guid)
$ouName = $guid
$initialPath = "OU=$($userNameSplit[0])," + (Get-ADDomain).DistinguishedName
$ouPath = "CN=ADFS," + $initialPath
$ou = "CN=" + $ouName + "," + $ouPath
Write-Host ("Creating organizational unit with DN: " + $ou)
if ($null -eq (Get-ADObject -Filter {distinguishedName -eq $ouPath}))
{
Write-Host ("First creating initial path " + $ouPath)
New-ADObject -Name "ADFS" -Type Container -Path $initialPath
}
New-ADObject -Name $ouName -Type Container -Path $ouPath
# get gMSA SID
$strSID = (Get-ADServiceAccount -Identity $userNameSplit[1]).SID
# set acl to ADFS cottainer object
Import-Module ActiveDirectory
try {
Push-Location ad:
[System.DirectoryServices.ActiveDirectorySecurityInheritance]$adSecInEnum = [System.DirectoryServices.ActiveDirectorySecurityInheritance]::All
$ace1 = New-Object System.DirectoryServices.ActiveDirectoryAccessRule $strSID,"GenericRead","Allow",$adSecInEnum
$ace2 = New-Object System.DirectoryServices.ActiveDirectoryAccessRule $strSID,"CreateChild","Allow",$adSecInEnum
$ace3 = New-Object System.DirectoryServices.ActiveDirectoryAccessRule $strSID,"WriteOwner","Allow",$adSecInEnum
$ace4 = New-Object System.DirectoryServices.ActiveDirectoryAccessRule $strSID,"DeleteTree","Allow",$adSecInEnum
$acl = Get-Acl -Path $ou
$acl.AddAccessRule($ace1)
$acl.AddAccessRule($ace2)
$acl.AddAccessRule($ace3)
$acl.AddAccessRule($ace4)
Set-Acl -Path $ou -AclObject $acl
} finally {
Pop-Location
}
return @{"DKMContainerDn" = $ou}
}
# ADFSコンテナーを作成し、設定情報を変数に格納
$adminConfig = New-NonDADkmContainerForgMSA 'ads\adfs-service'
# ADFS コンテナーが無事作成されたか確認します。(※著者の環境では、Active Directory ユーザーとコンピューターの管理ツールでは確認できませんでした。)
Get-ADObject -Filter * -SearchBase 'CN=ADFS,OU=ads,DC=ads,DC=cjbiz,DC=info'
4.ADFS サーバーの構築 (ADFSファームの構築)
これで準備が整いました。ADFS ファームを作るため、ADFS モジュールにある Install-AdfsFarm コマンドレットを使用していきます。
# ツールをインストール
Install-WindowsFeature -Name 'ADFS-Federation' -IncludeManagementTools
# 証明書情報を取得
$cert = Get-ChildItem Cert:\LocalMachine\My\ | Where-Object { $_.Subject -eq 'CN=*.cjbiz.info' }
# ADFSファームを構築する際のローカル管理者権限を持つユーザーの認証情報
$localAdminCred = Get-Credential 'ads\admin'
# SigningCertificateThumbprint, DecryptionCertificateThumbprint を指定してADFSファームを作成
$params = @{
CertificateThumbprint = $cert.Thumbprint
SigningCertificateThumbprint = $cert.Thumbprint
DecryptionCertificateThumbprint = $cert.Thumbprint
FederationServiceName = 'adfstest.cjbiz.info'
GroupServiceAccountIdentifier = 'ads\adfs-service$'
Credential = $localAdminCred
OverwriteConfiguration = $true
AdminConfiguration = $adminConfig
Verbose = $true
}
# 検証
Test-AdfsFarmInstallation @params
# インストール
Install-AdfsFarm @params
以上、その1は完了になります。
※その2へ続きます。
AWS Microsoft Managed AD にてAD FSを構築し、SAML のAmazon Grafana ログインの ID プロバイダー (IDP) として構成(その2)
参考
https://blog.esrij.com/2022/10/18/post-45843/
https://dev.classmethod.jp/articles/setup-adfs-server-on-aws-microsoft-ad/
https://docs.aws.amazon.com/ja_jp/grafana/latest/userguide/authentication-in-AMG-SAML.html