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トランスポートを使用するように指示することも必要です。そのためには、次のいずれかの方法で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では、LoginCredentials
実装としてPasswordCredentials
クラスを提供します。ストアでトランスポートとしてSSLを使用する必要がある場合は、認証を実行する前に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; }
ログインを処理するには、認証に必要なすべてのプロパティを含むフラット・テキスト・ファイルに認証資格証明を配置するという方法もあります。この方法が機能するためには、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; }
認証セッションが失効する場合があります。これは、複数の理由で発生する可能性があります。たとえば、ストアの管理者がセッションの延長を許可しないようにストアを構成し、セッションがタイムアウトした場合などです。これらのプロパティは、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; }