Oracle NoSQL Databaseは、クライアント・コードのストアへの認証が必要ない場合にインストールできます。(これを明確にするために、この本に示すほとんどの例では認証が実行されていなません。)ただし、ストアを安全な方法で操作する場合には、認証を必要とすることができます。その場合は、SSLと認証を使用するためのオーバーヘッドが必要になるため、パフォーマンス・コストがかかることに注意してください。本番環境のストアにはSSLを使用した認証を必要とするのがベスト・プラクティスですが、パフォーマンスが重要視されるサイトでは、そこまでのレベルのセキュリティを求めない場合があります。
認証では、ストア・ハンドルを取得した時点で、ストアにユーザー名とパスワード資格証明を送信します。認証をサポートするように構成されたストアでは、認証およびその他の機密情報が確実に保護されるように、クライアントとの通信にはSSLを使用することが自動的に構成されます。SSLを使用する場合、アクセス先のストアが信頼できることを検証するために、クライアント・コードが実行されるマシンにSSL証明書をインストールする必要があります。
ストアの認証用の構成については、『Oracle NoSQL Databaseセキュリティ・ガイド』で説明しています。
セキュアなストアを使用している場合、クライアント・コードとストア間のすべての通信は、認証資格証明も含めて、SSLを介してトランスポートされます。そのため、クライアント・コードでSSLを使用するように構成する必要があります。これを行うには、SSL証明書データがある場所を識別し、SSLトランスポートを使用することを別途指定します。
Oracle NoSQL DatabaseストアでSSLトランスポートを使用するように構成されると、セキュリティ構成ツールを使用して一連のセキュリティ・ファイルが生成されます。これらのファイルの1つであるclient.trust
ファイルを、Oracle NoSQL Databaseのクライアント・コードを実行するすべてのマシンにコピーする必要があります。
セキュリティ構成ツールの使用方法の詳細は、『Oracle NoSQL Databaseセキュリティ・ガイド』を参照してください。
client.trust
ファイルには、クライアントがストアとのSSL接続を確立するために必要な証明書が含まれているため、このファイルがある場所をコードに指定する必要があります。このファイルが置かれているマシン上の物理的なロケーションを指定するには、oracle.kv.ssl.trustStore
プロパティを使用します。このプロパティを設定するには、次の2つの方法を使用します。
トラスト・ストアの場所の識別にProperties
オブジェクトを使用してoracle.kv.ssl.trustStore
プロパティを設定します。次に、KVStoreConfig.setSecurityProperties()
を使用してProperties
オブジェクトをKVStore
ハンドルに渡します。
このメソッドを使用する場合は、プロパティ名としてKVSecurityConstants.SSL_TRUSTSTORE_FILE_PROPERTY
を使用します。
oracle.kv.security
プロパティを使用してclient.trust
ファイルなどのプロパティ・ファイルを参照します。そのファイルにoracle.kv.ssl.trustStore
プロパティを設定します。
client.trust
ファイルの場所の識別に加えて、SSLトランスポートを使用することをクライアント・コードに指定する必要があります。これを行うには、次の2つのうち1つの方法を使用して、oracle.kv.transport
プロパティを設定します。
トラスト・ストアの場所の識別にProperties
オブジェクトを使用してoracle.kv.transport
プロパティを設定します。次に、KVStoreConfig.setSecurityProperties()
を使用してProperties
オブジェクトをKVStore
ハンドルに渡します。
このメソッドを使用する場合は、プロパティ名としてKVSecurityConstants.TRANSPORT_PROPERTY
を使用し、プロパティの値としてKVSecurityConstants.SSL_TRANSPORT_NAME
を使用します。
oracle.kv.security
プロパティを使用してclient.trust
ファイルなどのプロパティ・ファイルを参照します。そのファイルにoracle.kv.transport
プロパティを設定します。
ストアへの認証を行うには、LoginCredentials
実装インスタンスにKVStoreFactory.getStore()
を指定します。Oracle NoSQL DatabaseではPasswordCredentials
クラスがLoginCredentials
実装として提供されます。ストアでのトランスポートにSSLの使用が必要とされている場合は、認証を実行する前にこれを構成します。(詳細は前の項を参照してください。)
認証の失敗を処理できるように、コードを準備しておく必要があります。認証が失敗した場合は、KVStoreFactory.getStore()
によってAuthenticationFailure
がスローされます。その例外を捕捉して問題に対処します。
セキュアなストアのストア・ハンドルを取得するための簡単な例を次に示します。この例ではSSLトランスポートを使用しています。
import java.util.Properties; import oracle.kv.AuthenticationFailure; import oracle.kv.PasswordCredentials; import oracle.kv.KVSecurityConstants; import oracle.kv.KVStoreConfig; import oracle.kv.KVStoreFactory; KVStore store = null; try { /* * storeName, hostName, port, username, and password are all * strings that would come from somewhere else in your * application. */ KVStoreConfig kconfig = new KVStoreConfig(storeName, hostName + ":" + port); /* Set the required security properties */ Properties secProps = new Properties(); secProps.setProperty(KVSecurityConstants.TRANSPORT_PROPERTY, KVSecurityConstants.SSL_TRANSPORT_NAME); secProps.setProperty (KVSecurityConstants.SSL_TRUSTSTORE_FILE_PROPERTY, "/home/kv/client.trust"); kconfig.setSecurityProperties(secProps); store = KVStoreFactory.getStore(kconfig, new PasswordCredentials(username, password.toCharArray())); null /* ReauthenticateHandler */); } catch (AuthenticationFailureException afe) { /* * Could potentially retry the login, possibly with different * credentials, but in this simple example, we just fail the * attempt. */ System.out.println("authentication failed!") return; }
ログインを処理するもう1つの方法として、認証に必要なすべてのプロパティを含んだ認証資格証明をフラット・テキスト・ファイルで用意する方法があります。これが機能するためには、Oracle NoSQL Databaseストア用のパスワード・ストアを構成してあることが必要になります。(パスワード・ストアの設定の詳細は、『Oracle NoSQL Databaseセキュリティ・ガイド』を参照してください。)
たとえば、パスワード・ファイルのパスワード・ストアを使用するようにストアが構成されており、パスワードがlogin.pwd
というファイルに含まれているとします。その場合、login.txt
という名前の次のようなログイン・プロパティ・ファイルを作成する必要があります。
oracle.kv.auth.username=clientUID1 oracle.kv.auth.pwdfile.file=/home/nosql/login.pwd oracle.kv.transport=ssl oracle.kv.ssl.trustStore=/home/nosql/client.trust
この場合、次のようにして認証を実行できます。
import oracle.kv.AuthenticationFailure; import oracle.kv.PasswordCredentials; import oracle.kv.KVStoreConfig; import oracle.kv.KVStoreFactory; /* the client gets login credentials from the login.txt file */ /* can be set on command line as well */ System.setProperty("oracle.kv.security", "/home/nosql/login.txt"); KVStore store = null; try { /* * storeName, hostName, port are all strings that would come * from somewhere else in your application. * * Notice that we do not pass in any login credentials. * All of that information comes from login.txt */ myStoreHandle = KVStoreFactory.getStore( new KVStoreConfig(storeName, hostName + ":" + port)) } catch (AuthenticationFailureException afe) { /* * Could potentially retry the login, possibly with different * credentials, but in this simple example, we just fail the * attempt. */ System.out.println("authentication failed!") return; }
認証セッションは期限切れになることがあります。これにはいくつかの理由が考えられます。1つには、ストアの管理者がセッションの延長を許可しないようにストアを構成しており、セッションがタイムアウトした場合です。これらのプロパティは、sessionExtendAllow
とsessionTimeout
を使用して構成します。これらのプロパティの詳細は、『Oracle NoSQL Databaseセキュリティ・ガイド』を参照してください。
ストアになんらかの重大な混乱が生じて認証セッションが無効化された場合には、再認証も必要になります。これは、本番環境のストアでは起こることがほとんどない異常な状況です。開発環境にインストールされているストアの場合、特に再起動が頻繁に行われるようなストアでは、この状況が発生することがあります。
認証セッションは、ライフタイムのあらゆる時点において、アプリケーションによって期限切れとして検出される場合があるため、認証セッションの期限切れに対応できる、エラーで停止しない堅牢なコードを記述する必要があります。
認証セッションが期限切れになった場合、デフォルトでは、ストアへのアクセスを試行するメソッドによってAuthenticationRequiredException
がスローされます。これを確認したら、ストアへの再認証を行い、失敗した操作を再試行するようにコードを記述します。
KVStore.login()
メソッドを使用して、ストアへの再認証を手動で行うことができます。このメソッドでは、LoginCredentials
クラス・インスタンス(PasswordCredentials
など)を使用してしてログイン資格証明を指定することが必要になります。
try { ... /* Store access code happens here */ ... } catch (AuthenticationRequiredException are) { /* * myStoreHandle is a KVStore class instance. * * pwCreds is a PasswordCredentials class instance, obtained * from somewhere else in your code. */ myStoreHandle.login(pwCreds); }
これは、前の項で説明したoracle.kv.auth.username
プロパティとoracle.kv.auth.pwdfile.file
プロパティを使用している場合には必要ありません。その場合、Oracle NoSQL Databaseクライアント・コードは、それらのプロパティで指定された値を使用してクライアントを自動的かつ暗黙的に再認証します。
3つ目の選択肢として、再認証を実行するためのReauthenticationHandler
クラス実装を作成する方法があります。この方法は、KVStoreFactory.getStore()
のコールにLoginCredentials
実装インスタンス(つまりPasswordCredentials
)を指定しており、AuthenticationRequiredException
の捕捉による後続の再試行操作を行わない場合にのみ必要です。
このマニュアルでは、ReauthenticationHandler
の完全な実装例を示していません(実装例は非常に詳細な固有の要件に基づくものであり、すべてのサイトに適用できるものではないと考えられるからです)。ただし参考までに、非常に簡素で大まかなReauthenticationHandler
の実装例を次に示します。
package kvstore.basicExample import oracle.kv.ReauthenticationHandler; import oracle.kv.PasswordCredentials; public class MyReauthHandler implements ReauthenticationHandler { public void reauthenticate(KVStore reauthStore) { /* * The code to obtain the username and password strings would * go here. This should be consistent with the code to perform * simple authentication for your client. */ PasswordCredentials cred = new PasswordCredentials(username, password.toCharArray()); reauthStore.login(cred); } }
ストア・ハンドルを取得したら、MyReauthHandler
インスタンスを指定します。
import java.util.Properties; import oracle.kv.AuthenticationFailure; import oracle.kv.PasswordCredentials; import oracle.kv.KVSecurityConstants; import oracle.kv.KVStoreConfig; import oracle.kv.KVStoreFactory; import kvstore.basicExample.MyReauthHandler; KVStore store = null; try { /* * storeName, hostName, port, username, and password are all * strings that would come from somewhere else in your * application. The code you use to obtain your username * and password should be consistent with the code used to * obtain that information in MyReauthHandler. */ KVStoreConfig kconfig = new KVStoreConfig(storeName, hostName + ":" + port); /* Set the required security properties */ Properties secProps = new Properties(); secProps.setProperty(KVSecurityConstants.TRANSPORT_PROPERTY, KVSecurityConstants.SSL_TRANSPORT_NAME); secProps.setProperty (KVSecurityConstants.SSL_TRUSTSTORE_FILE_PROPERTY, "/home/kv/client.trust"); kconfig.setSecurityProperties(secProps); store = KVStoreFactory.getStore(kconfig, new PasswordCredentials(username, password.toCharArray())); new MyReauthHandler()); } catch (AuthenticationFailureException afe) { /* * Could potentially retry the login, possibly with different * credentials, but in this simple example, we just fail the * attempt. */ System.out.println("authentication failed!") return; }
ストアを認証する必要のあるクライアントには、ストアに対する一定のアクセス権限が付与されます。この範囲は、権限の一部からすべての、完全なアクセス権限までになります。アクセス権限の量は、認証ユーザーに付与されるロールおよび権限によって定義されます。このため、Oracle NoSQL Database APIへのコールは、操作を実行する認可がないために失敗する可能性があります。このような場合には、UnauthorizedException
がスローされるようになります。
ユーザーにロールおよび権限を定義する方法の詳細は、『Oracle NoSQL Databaseセキュリティ・ガイド』を参照してください。
UnauthorizedException
がスローされた場合、操作は再試行されません。かわりに、操作が完全に中止されるか、操作の実行に必要な権限を持つ別の資格証明を使用して、コードによる再認証が試行されます。クライアントはKVStore.logout()
を使用してストアからログアウトできます。前の項で説明したように、コードのログインが戻る方法はストアのアクセス権の構成によって決まります。
// Open a store handle, and perform authentication as you do // as described earlier in this section. ... try { // When you attempt some operation (such as a put or delete) // to a secure store, you should catch UnauthorizedException // in case the user credentials you are using do not have the // privileges necessary to perform the operation. } catch (UnauthorizedException ue) { /* * When you see this, either abandon the operation entirely, * or log out and log back in with credentials that might * have the proper permissions for the operation. */ System.out.println("authorization failed!") return; }