Encontrar

Article
· Dec 22 8m read

アプリケーションの認証を独自の方法で行いたい場合に利用できる代行(委譲)認証について

これは InterSystems FAQ サイトの記事です。

InterSystems 製品で利用できる ID およびアクセスの管理には、Kerberos、OS ベース、InterSystems ログイン(=インスタンス認証/パスワード認証)、2 要素認証、JWT 認証、LDAP 認証(AD も含む)、OAuth2 などが用意されていますが、これらのどの方法にも当てはめることのできない独自の管理方法をお持ちの場合に利用できる方法があり「代行認証」(または委譲認証)と呼びます。

ドキュメント:代行認証

このトピックでは、代行認証を行うまでの手続きについて解説します。

サンプルコードはこちら👉https://github.com/Intersystems-jp/FAQ-716

シナリオとして、アプリケーション用ユーザ名、パスワードを管理する専用テーブルがあるとしています。特定の REST API のログイン、またはターミナルアクセス利用時にこの情報を使用して代行認証を行う方法を解説します。

大まかな手順は以下の通りです。

[1] 専用ルーチンを作成する

[2] システム・セキュリティの認証/ウェブセッションオプションを変更する

[3] 使用するサービスに対して代行認証を有効化する

[4] テストする

 


[1] 専用ルーチンを作成する

以下の流れで作成します。

1、サンプルコードのダウンロード

2、コードのインポート

3、コードの修正

 

1、サンプルコードのダウンロード

https://github.com/Intersystems-jp/FAQ-716 を使用します。

git clone または、以下の画面例にあるように緑の [<> Code] ボタンをクリックし、[Download ZIP] からダウンロードを行ってください。

 

2、コードのインポート

ダウンロードしたコードを InterSystems 製品にインポートします。

%SYS ネームスペースに接続した状態でインポートします。

※ Zから始まるルーチンやパッケージ名はアップグレードインストールを行っても消去されないルールがあります。ダウンロードしたルーチン名のままインポートを行ってください。

インポート方法はお好みの方法をご利用ください。(IDE、管理ポータルなど)

 

3、コードの修正

例では、%SYS ネームスペースに ZTest.Credentials テーブルを用意し、ユーザ名とパスワードの管理が行われていると仮定しています(ユーザ名、パスワードの管理を行うテーブル、チェック用ルーチンやメソッドは任意のネームスペースに配置することができますが、例では、Zから始まる名称の専用テーブル(=クラス)を用意し、%SYS に配置しています)。

代行認証を行うときにユーザから入力されるユーザ名、パスワードは  ZAUTHENTICATE ルーチンの ZAUTHETICATE() 関数で受け取ることができます。

シグニチャは以下の通りです。

ZAUTHENTICATE(ServiceName,Namespace,Username,Password,Credentials,Properties) PUBLIC {

引数の仕様は以下の通りです。

  • ServiceName:認証時に使用しているサービス名が入ります。(例:%Service_Console)
  • Namespace:認証通過時のアクセス先ネームスペース名
  • Uesrname:認証時にユーザが入力したユーザ名
  • Paswword:認証時にユーザが入力したパスワード
  • Credentials:(未使用)
  • Properties:参照渡し。Username のユーザに対する属性を指定できます(ログインロールなど指定できます)

詳しくは、ドキュメントもご参照ください。「代行認証-シグニチャ

ZAUTHENTICATE() 関数に、代行認証を使用するように設定したサービスから渡される認証情報を元に、アプリケーション用データを利用したユーザ名、パスワードのチェックを行い、認証の成功/失敗を評価します。

例えば、ターミナルアクセス時:%Service_Console、iris session:%Service_Terminal を利用したときのチェックは以下のように記載します。

  If (ServiceName="%Service_Console")||(ServiceName="%Service_Terminal") {
    set result=##class(ZTest.Credentials).check($GET(Username),$GET(Password))
    //認証失敗時
    if result=0 {
      return $SYSTEM.Status.Error($$$GeneralError,"ユーザ認証失敗 Username="_$GET(Username))
    }
    set Properties("Roles")="%Developer,%DB_USER"
    set Properties("NameSpace")="USER"
    return $SYSTEM.Status.OK()
  }

特定の REST アプリケーション /hello に対して使用する場合は以下の通りです。

REST アクセス時、サーバ側では、HTTP 要求の内容を %request 変数に格納します。チェックとしては、 %request変数にインスタンスが格納されているかどうか、また、格納されている場合、Application プロパティに REST のエンドポイントとして設定したパス名が含まれているかをチェックします。

含まれている場合、アプリケーションで用意した認証チェックを実行します。

  //特定のRESTアプリから来た場合
  If $isobject($get(%request)) { 
    If %request.Application["/hello" {
      set result=##class(ZTest.Credentials).check($GET(Username),$GET(Password))
      //認証失敗時
      if result=0 {
        return $SYSTEM.Status.Error($$$GeneralError,"ユーザ認証失敗 Username="_$GET(Username))
      }
      set Properties("Roles")="%Developer,%DB_USER"
      return $SYSTEM.Status.OK()
    }
  }

コード全体はこちらをご覧ください。

$SYSTEM.Status.OK() を戻すと認証が成功したことを意味します。

失敗時は、以下メソッドを使用してエラーの理由をエラーステータスとして戻せます

$SYSTEM.Status.Error($$$GeneralError,"任意文字列")

認証失敗の場合は ZAUTHENTICATE から返したエラーが監査に記録されるのでそれを確認できます。

メモ:サンプルコードでは、ログインしようとしたユーザにはアクセスが拒否されたことだけが通知され、認証失敗の理由までは表示されません。もし、失敗理由を含めて監査に記録したい場合は、ZAUTHENTICATE ルーチン内でエラー条件に合わせシステム提供マクロを使用しながらエラーを返す工夫が必要です。

詳しくは、[4] テストする をご参照ください。

 

[2] システム・セキュリティの認証/ウェブセッションオプションを変更する

ZAUTHENTICATE ルーチンの準備が整ったら、代行認証に関するシステムワイドの設定を変更します。

管理ポータル > [システム管理] > [セキュリティ] > [システム・セキュリティ] > [認証/ウェブセッションオプション]を開き、「委譲認証(または代行認証)を許可」にチェックを入れます。

[3] 使用するサービスに対して代行認証を有効化する

代行認証を使用する接続経路であるサービスの設定を行います。

管理ポータル > [システム管理] > [セキュリティ] > [サービス]

ターミナルにログインする場合のサービスは以下の通りです。

  •  Windowsのターミナルアクセスに対するサービスは、%Service_Console
  •  Windows以外で iris session を利用してIRISにログインするときのサービスは、%Service_Terminal

対象のサービスの認証方式を「委譲(または代行)」のみをチェックし、保存します。

%Service_Terminalの例

 

特定のREST用パスに対する設定は以下の通りです。(例:/hello のパスに対する設定)

管理ポータル > [システム管理] > [セキュリティ] > [アプリケーション] > [ウェブ・アプリケーション] > パス名選択 > 許可された認証方法:委譲(または代行)のみチェックして保存

 

[4] テストする

 

[4]-1 ターミナルにログイン

正しいユーザ名、パスワードの組み合わせを入力するとログインできます。

iris session でログインしたときの成功時の例(ユーザ名:jamesmichael)と失敗時の例(ユーザ名:SuperUser)です。

ユーザ名:jamesmichael のパスワードは、oj9`b`PJB{tH|\ です。

ダミーユーザのパスワードについては、ZTest.Credentials クラスの ceatedummydata()をご参照ください。

irisowner@46f7d0610414:/opt/src$ iris session iris

ノード: 46f7d0610414 インスタンス: IRIS

ユーザ名:jamesmichael
パスワード:**************
USER>write $username
jamesmichael
USER>h
irisowner@46f7d0610414:/opt/src$ iris session iris

ノード: 46f7d0610414 インスタンス: IRIS

ユーザ名:SuperUser
パスワード:***
アクセスが拒否されました。

ユーザ名:

 

[4]-2 RESTアプリのBasic認証でテスト

REST アプリのBasic認証にアプリ内で利用するユーザ名、パスワードの組み合わせを指定し、ログインできるか確認します。

認証を失敗すると 401 Unauthorized が返ります。

POSTMANでの実行例です。

失敗時の例です。

また、ログインが成功すると、「代行ユーザ」というタイプでInterSystems製品内ユーザとして登録されます。このユーザは、管理ポータルで削除以外の編集作業は行えないユーザとして登録されます(管理ポータル > システム管理 > セキュリティ > ユーザ )。

認証失敗を確認するには、監査を使用すると便利です。

監査は、[システム管理] > [セキュリティ] > [監査] > [監査データベースの閲覧] のページで確認できます(検索ボタンを押すとレコードの中身が表示されます)。

イベント:LoginFailure で記録されるので、該当行の詳細リンクをクリックします。

もし、監査が無効になっている場合には、以下メニューで監査を有効に設定し、確認してください。

[システム管理] > [セキュリティ] > [監査] > [監査を有効に]

監査が有効になっていない場合、システムイベント  %System/%Login/Login とLoginFailure  の状態を確認し、[Enabled] 列が[はい] になっていない場合は変更します。手順は以下の通りです。

[システム管理] > [セキュリティ] > [監査] > [システムイベントを構成] 

%System/%Login/Login とLoginFailure の行の [Enabled]  [はい] になっているかご確認ください。[いいえ] になっている場合は、[状態変更] を1度クリックし [はい] に変更してください。

Discussion (0)1
Log in or sign up to continue
Digest
· Dec 22

Publicações Desenvolvedores InterSystems, Dezembro 15 - 21, 2025, Resumo

Question
· Dec 22

How to make IRISLIB/HSLIB writable on Docker?

I know this is not recommended but I need to investigate a bug and to modify some system classes.
When I set the "Mount as read-only" flag to "off" IRIS says:

ERROR #43: the write daemon failed to set the READ/WRITE flag in IRISLIB
This database is mounted as read-only due to 'Failed to access iris.lck file'!
Discussion (0)2
Log in or sign up to continue
Article
· Dec 22 2m read

Índices: O Poder Silencioso por Trás de Consultas Rápidas

O Poder da Indexação em Tabelas de Banco de Dados

Ao trabalhar com bancos de dados, a maioria dos desenvolvedores entende o conceito de um índice e por que ele é usado: para acelerar a recuperação de dados. Mas o real impacto da indexação muitas vezes só fica claro quando comparamos cenários com e sem ela.

Você sabe o que acontece sem um índice?
Imagine uma tabela com três colunas: Name, Age, e MobileNumber.


Considere esta consulta:

Se a coluna Idade (Age) não tiver um índice, o motor do banco de dados irá:

  • Verificar se o campo da condição WHERE possui um índice.
  • Se não houver, ele fará uma varredura completa da tabela.
  • Para cada linha, ele verificará o valor da Idade e retornará as correspondências.

Isso significa que o motor atravessa toda a estrutura de dados, o que consome muito tempo em tabelas grandes.

O que acontece com um índice?

Agora, se a coluna Idade estiver indexada, o processo muda drasticamente:

  • O motor vai diretamente para a estrutura do índice.
  • Ele encontra o nó para Idade = 26.
  • O índice aponta para os IDs de registro correspondentes na tabela principal.
  • O resultado é obtido quase instantaneamente.

É por isso que a indexação é uma ferramenta de otimização tão poderosa.

Uma Lição da Vida Real
Recentemente, encontramos uma situação interessante que destacou a importância dos índices. Nossa tabela tinha 5 registros e a coluna Idade estava indexada. Então, por engano, excluímos duas entradas da estrutura do índice (não da tabela principal). Essas entradas correspondiam aos IDs X001 e X005, ambos com Idade = 26.


Quando executamos:
SELECT ID, Age, EmpId, Mobile, NameFROM Company.Employee WHERE Age = 26 

Esperávamos 3 registros (já que a tabela principal ainda os tinha), mas apenas 2 registros apareceram.

Por quê? Porque a consulta confiou no índice, e o índice estava incompleto.

Conclusão Principal
Os índices são poderosos, mas devem ser mantidos adequadamente. Se um índice for excluído acidentalmente ou corrompido, não se preocupe; você pode reconstruí-lo usando o comando abaixo:

Do ##Class(Company.Employee).%BuildIndices()

Moral da história: Índices tornam as consultas rápidas, mas também se tornam a "fonte única da verdade" para a recuperação. Manipule-os com cuidado! 😅

Discussion (0)1
Log in or sign up to continue
Announcement
· Dec 22

Season’s Greetings to the Developer Community

Dear Community,

As the 🎄 Festive Season 🎄 approaches, we’re excited to send our warmest wishes your way. May your holidays be filled with the joy of 🧑‍💻 learning, 🫂 connecting with fellow developers, and the thrill of new ideas and challenges waiting in the year ahead!

Looking back on 2025, we’re delighted to celebrate another year of remarkable achievements together with YOU, our incredible members:

✨ Developer Community celebrated the 10-Year Anniversary and continued to grow with thousands of new members and contributors!
✨ On Developer Community, we expanded our Developer Community AI capabilities and improved search
Open Exchange surpassed 1,100 applications, including new tools, frameworks, and integrations
✨ On Ideas Portal you suggested overall 600 incredible ideas and bug reports, with many now in progress or already implemented
Global Masters introduced new challenges, badges, and seasonal quests that kept engagement at an all-time high

A heartfelt THANK YOU to our brilliant members, and to our dedicated moderators and admins, for keeping this community vibrant, collaborative, and inspiring. Your passion and innovation continue to elevate the ecosystem every single day.

Here’s to more coding, learning, and connection in the year ahead. Wishing you a joyful holiday season and an innovative 2026! 🥳🎄✨

With gratitude,
The Developer Relations Team ❤️

1 new Comment
Discussion (1)1
Log in or sign up to continue