ADFSでSQL Server以外のDBから属性を取得する場合
1.はじめに
以前、SAMLの調査でいろいろ試したことをサルベージして記載しています。
ニッチ過ぎて使い道がほぼない。。。
2.DBから属性を取得する
- SQL Serverから取得する場合は、要求規則にSQL文を設定すれば取得可能
- SQL Server以外はC#で作成した自作のDLLが必要
3.C#のDLLソース
- SQLはpostgresqlを使用
- Visual Stadioのプロジェクトで下記のDLLを参照設定する(Microsoft.~のDLLはWindows Serverある)
- Microsoft.IdentityModel
- Microsoft.IdentityServer.ClaimsPolicy
- Npgsql
using Npgsql;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using RemotingMessagingAsyncResult = System.Runtime.Remoting.Messaging.AsyncResult;
using Microsoft.IdentityModel.Threading;
using Microsoft.IdentityServer.ClaimsPolicy.Engine.AttributeStore;
namespace ClassLibrary1
{
public class CustomAttributeStore : IAttributeStore
{
static readonly string EVENT_LOG_NAME = "CustomAttributeStore";
static readonly string CONFIG_KEY01 = "CONNECTION_INFO";
NpgsqlConnection _connection = null;
string _connInfo = null;
delegate string[][] RunQueryDelegate(string formatQuery);
~CustomAttributeStore()
{
//EventLog.WriteEntry(EVENT_LOG_NAME, "~CustomAttributeStore", EventLogEntryType.Information, 1, 100, null);
// コネクションのクローズ
_connection.Close();
}
public void Initialize(Dictionary<string, string> config)
{
/*
if (!EventLog.SourceExists(EVENT_LOG_NAME))
{
EventLog.CreateEventSource(EVENT_LOG_NAME, "");
}
EventLog.WriteEntry(EVENT_LOG_NAME, "Initialize", EventLogEntryType.Information, 1, 100, null);
*/
if (!config.TryGetValue(CONFIG_KEY01, out _connInfo))
{
throw new AttributeStoreInvalidConfigurationException("DB接続情報未設定");
}
// コネクションのオープン
_connection = new NpgsqlConnection(_connInfo);
_connection.Open();
}
public IAsyncResult BeginExecuteQuery(string query, string[] parameters, AsyncCallback callback, object state)
{
//EventLog.WriteEntry(EVENT_LOG_NAME, "BeginExecuteQuery", EventLogEntryType.Information, 1, 100, null);
if (String.IsNullOrEmpty(query))
{
throw new AttributeStoreQueryFormatException("クエリ未設定");
}
RunQueryDelegate runQueryDelegate = new RunQueryDelegate(RunQuery);
TypedAsyncResult<string[][]> asyncResult = new TypedAsyncResult<string[][]>(callback, state);
runQueryDelegate.BeginInvoke(string.Format(query, parameters), new AsyncCallback(AsyncQueryCallback), asyncResult);
return asyncResult;
}
public string[][] EndExecuteQuery(IAsyncResult result)
{
//EventLog.WriteEntry(EVENT_LOG_NAME, "EndExecuteQuery", EventLogEntryType.Information, 1, 100, null);
return TypedAsyncResult<string[][]>.End(result);
}
private string[][] RunQuery(string formatQuery)
{
//EventLog.WriteEntry(EVENT_LOG_NAME, "RunQuery", EventLogEntryType.Information, 1, 100, null);
//EventLog.WriteEntry(EVENT_LOG_NAME, formatQuery, EventLogEntryType.Information, 1, 100, null);
// SQL実行&結果取得
NpgsqlCommand command = new NpgsqlCommand(formatQuery, _connection);
String data = null;
using (NpgsqlDataReader reader = command.ExecuteReader())
{
if (reader.Read())
{
data = reader[0].ToString();
}
}
string[][] result = { new[] { data } };
return result;
}
private void AsyncQueryCallback(IAsyncResult result)
{
//EventLog.WriteEntry(EVENT_LOG_NAME, "AsyncQueryCallback", EventLogEntryType.Information, 1, 100, null);
TypedAsyncResult<string[][]> asyncResult = (TypedAsyncResult<string[][]>)result.AsyncState;
RunQueryDelegate runQueryDelegate = (RunQueryDelegate)((RemotingMessagingAsyncResult)result).AsyncDelegate;
string[][] values = null;
Exception originalException = null;
try
{
values = runQueryDelegate.EndInvoke(result);
}
catch (Exception e)
{
originalException = e;
}
asyncResult.Complete(values, false, originalException);
}
}
}
4.設定
- 作成したDLLをWindows\ADFS直下に配置する。
- 下記を参考に、要求記述を追加する。
- SQLはpostgresqlを使用
- Visual Stadioのプロジェクトで下記のDLLを参照設定する(Microsoft.~のDLLはWindows Serverある)
- Microsoft.IdentityModel
- Microsoft.IdentityServer.ClaimsPolicy
- Npgsql
using Npgsql;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using RemotingMessagingAsyncResult = System.Runtime.Remoting.Messaging.AsyncResult;
using Microsoft.IdentityModel.Threading;
using Microsoft.IdentityServer.ClaimsPolicy.Engine.AttributeStore;
namespace ClassLibrary1
{
public class CustomAttributeStore : IAttributeStore
{
static readonly string EVENT_LOG_NAME = "CustomAttributeStore";
static readonly string CONFIG_KEY01 = "CONNECTION_INFO";
NpgsqlConnection _connection = null;
string _connInfo = null;
delegate string[][] RunQueryDelegate(string formatQuery);
~CustomAttributeStore()
{
//EventLog.WriteEntry(EVENT_LOG_NAME, "~CustomAttributeStore", EventLogEntryType.Information, 1, 100, null);
// コネクションのクローズ
_connection.Close();
}
public void Initialize(Dictionary<string, string> config)
{
/*
if (!EventLog.SourceExists(EVENT_LOG_NAME))
{
EventLog.CreateEventSource(EVENT_LOG_NAME, "");
}
EventLog.WriteEntry(EVENT_LOG_NAME, "Initialize", EventLogEntryType.Information, 1, 100, null);
*/
if (!config.TryGetValue(CONFIG_KEY01, out _connInfo))
{
throw new AttributeStoreInvalidConfigurationException("DB接続情報未設定");
}
// コネクションのオープン
_connection = new NpgsqlConnection(_connInfo);
_connection.Open();
}
public IAsyncResult BeginExecuteQuery(string query, string[] parameters, AsyncCallback callback, object state)
{
//EventLog.WriteEntry(EVENT_LOG_NAME, "BeginExecuteQuery", EventLogEntryType.Information, 1, 100, null);
if (String.IsNullOrEmpty(query))
{
throw new AttributeStoreQueryFormatException("クエリ未設定");
}
RunQueryDelegate runQueryDelegate = new RunQueryDelegate(RunQuery);
TypedAsyncResult<string[][]> asyncResult = new TypedAsyncResult<string[][]>(callback, state);
runQueryDelegate.BeginInvoke(string.Format(query, parameters), new AsyncCallback(AsyncQueryCallback), asyncResult);
return asyncResult;
}
public string[][] EndExecuteQuery(IAsyncResult result)
{
//EventLog.WriteEntry(EVENT_LOG_NAME, "EndExecuteQuery", EventLogEntryType.Information, 1, 100, null);
return TypedAsyncResult<string[][]>.End(result);
}
private string[][] RunQuery(string formatQuery)
{
//EventLog.WriteEntry(EVENT_LOG_NAME, "RunQuery", EventLogEntryType.Information, 1, 100, null);
//EventLog.WriteEntry(EVENT_LOG_NAME, formatQuery, EventLogEntryType.Information, 1, 100, null);
// SQL実行&結果取得
NpgsqlCommand command = new NpgsqlCommand(formatQuery, _connection);
String data = null;
using (NpgsqlDataReader reader = command.ExecuteReader())
{
if (reader.Read())
{
data = reader[0].ToString();
}
}
string[][] result = { new[] { data } };
return result;
}
private void AsyncQueryCallback(IAsyncResult result)
{
//EventLog.WriteEntry(EVENT_LOG_NAME, "AsyncQueryCallback", EventLogEntryType.Information, 1, 100, null);
TypedAsyncResult<string[][]> asyncResult = (TypedAsyncResult<string[][]>)result.AsyncState;
RunQueryDelegate runQueryDelegate = (RunQueryDelegate)((RemotingMessagingAsyncResult)result).AsyncDelegate;
string[][] values = null;
Exception originalException = null;
try
{
values = runQueryDelegate.EndInvoke(result);
}
catch (Exception e)
{
originalException = e;
}
asyncResult.Complete(values, false, originalException);
}
}
}
4.設定
- 作成したDLLをWindows\ADFS直下に配置する。
- 下記を参考に、要求記述を追加する。
名称 | 設定値 |
---|---|
表示名 | 返却ID |
要求識別子 | https://test.saml.local/returnid |
- 下記を参考に、カスタム属性ストアを追加する。
名称 | 設定値 |
---|---|
表示名 | test_Custom |
カスタム属性ストアのクラス名 | DLL名.クラス名,DLL名 |
オプションの初期化パラメータ 名前 | CONNECTION_INFO |
オプションの初期化パラメータ 値 | Server=localhost;Port=5432;User Id=postgres;Password=password;Database=testdb |
- 下記を参考に、要求規則を追加する。
名称 | 設定値 |
---|---|
要求規則名 | test |
カスタム規則 | c:[Type == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn"] => issue(store = "test_Custom", types = ("https://test.saml.local/returnid"), query = "select returnid1 from t_user where id = '{0}'", param = c.Value); |
- カスタム規則の設定値は下記のようになっています。
設定値 | 説明 |
---|---|
c:[Type~] | 指定したURIに対応する値がcに設定される 上記のURLはログイン名を指す |
store | 「属性ストア」の表示名を設定する |
types | 「要求記述」で追加したURIを設定する このURIがsamlの属性名として返却される |
query | 実行するSQLを設定する この取得値がsamlの属性値として返却される |
param | SQLのパラメータ [c.Value]でcに設定された値を条件値として設定される |
Author And Source
この問題について(ADFSでSQL Server以外のDBから属性を取得する場合), 我々は、より多くの情報をここで見つけました https://qiita.com/teradatk/items/8f755701eb30d9691a9c著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .