module poaBank { interface Account { | exception InsufficientFunds {}; | | float deposit(in float sum); | | float withdraw(in float sum) raises (InsufficientFunds); | | readonly attribute float balance; }; interface Bank { | exception noSuchAccount {}; | | Account getAccount(in long accountNum) raises (noSuchAccount); }; };
package poaBankSecureOld; import util.Util; import org.omg.CORBA.ORB; import org.omg.CORBA.Policy; import org.omg.CosNaming.NameComponent; import org.omg.CosNaming.NamingContext; import org.omg.CosNaming.NamingContextHelper; import org.omg.CosNaming.NamingContextPackage.NotFound; import com.sssw.jbroker.api.PortableServer.POA; import com.sssw.jbroker.api.security.QualityOfProtection; import org.omg.PortableServer.Servant; import org.omg.PortableServer.LifespanPolicyValue; import org.omg.PortableServer.IdAssignmentPolicyValue; import poaBank.Bank; import poaBank.BankHelper; public class Server { public static void main(String[] args) { | try { | | | | // create the jBroker ORB | | ORB orb = ORB.init(args, null); | | | | // get the root POA | | POA rootPOA = (POA) orb.resolve_initial_references("RootPOA"); | | | | // create a persistent user assigned ids POA | | POA bankPOA = (POA) rootPOA.create_POA("bankPOA", | | rootPOA.the_POAManager(), | | new Policy[] { | | | rootPOA.create_id_assignment_policy( | | | IdAssignmentPolicyValue.USER_ID), | | | rootPOA.create_lifespan_policy( | | | LifespanPolicyValue.PERSISTENT), | | | rootPOA.create_security_policy("bank") | | }); | | | | // create and activate bank servant | | Servant bank = new BankImpl(orb, bankPOA, args[0]); | | bankPOA.activate_object_with_id("bank".getBytes(), bank); | | | | // get the root of the NameService | | NamingContext root = NamingContextHelper.narrow( | | orb.resolve_initial_references("NameService")); | | | | // if not done before, publish the bank objref | | NameComponent nc = new NameComponent("secureBankOld", ""); | | NameComponent[] name = new NameComponent[] { nc }; | | try { | | | root.resolve(name); | | } catch (NotFound ex) { | | | // create the bank objref | | | Bank bankObj = BankHelper.narrow(bankPOA. | | | create_reference_with_id("bank".getBytes(), | | | bank._all_interfaces(null, null)[0])); | | | | | | System.out.println(orb.object_to_string(bankObj)); | | | root.rebind(name, bankObj); | | } | | | | // activate bankPOA | | bankPOA.the_POAManager().activate(); | | | | // wait for invocations | | System.out.println("waiting for invocations ..."); | | orb.run(); | | | } catch (Exception ex) { | | ex.printStackTrace(); | } } }
package poaBankSecureOld; import java.io.File; import org.omg.CORBA.ORB; import org.omg.CORBA.Policy; import org.omg.PortableServer.POA; import org.omg.PortableServer.Servant; import org.omg.PortableServer.POAPackage.WrongPolicy; import org.omg.PortableServer.IdUniquenessPolicyValue; import org.omg.PortableServer.IdAssignmentPolicyValue; import org.omg.PortableServer.ServantRetentionPolicyValue; import org.omg.PortableServer.RequestProcessingPolicyValue; import com.sssw.jbroker.api.security.SecurityCurrent; import poaBank.BankPOA; import poaBank.Account; import poaBank.AccountHelper; import poaBank.BankPackage.noSuchAccount; qpublic class BankImpl extends BankPOA { ORB _orb; POA _acctPOA; String _acctRepId; // repository Id for Account Objects Servant _defaultServant; SecurityCurrent _securityCurrent; BankImpl(ORB orb, POA bankPOA, String dir) throws Exception { | _orb = orb; | | // make sure that the DB dir exists | File dbDir = new File (dir); | if (!dbDir.exists()) dbDir.mkdir(); | | // get the securtity current | _securityCurrent = (SecurityCurrent) _orb.resolve_initial_references( | "SecurityCurrent"); | | // create the POA for Transient Account Objects | _acctPOA = bankPOA.create_POA("acctPOA", bankPOA.the_POAManager(), | new Policy[] { | | bankPOA.create_id_assignment_policy( | | IdAssignmentPolicyValue.USER_ID), | | bankPOA.create_request_processing_policy( | | RequestProcessingPolicyValue.USE_DEFAULT_SERVANT), | | bankPOA.create_id_uniqueness_policy( | | IdUniquenessPolicyValue.MULTIPLE_ID) | }); | | // set the servant manager in Acct POA | _defaultServant = new AccountImpl(_orb, dbDir); | _acctPOA.set_servant(_defaultServant); | | // compute the repository id for Account objects | _acctRepId = _defaultServant._all_interfaces(null, null)[0]; } public Account getAccount(int acctNum) throws noSuchAccount { | Account account = null; | | // print out the IP Address of the caller | System.out.println(_securityCurrent.getInetAddress()); | | if ((acctNum >= 100) && (acctNum < 110)) { | | | | // construct the object id for account | | byte objectId[] = new byte[1]; | | objectId[0] = (byte) (acctNum & 0xFF); | | | | try { | | | account = AccountHelper.narrow(_acctPOA. | | | create_reference_with_id(objectId, _acctRepId)); | | } catch (WrongPolicy ex) { // remove on JDK1.4 | | | ex.printStackTrace(); | | } | } | | if (account == null) throw new noSuchAccount(); | | return account; } }
この例では、アカウントデータストアがローカルのJavaオブジェクトです。アカウントデータストアがリモートオブジェクトである場合(別の場所で実行されている可能性があります)、識別「bankserver」がそれに伝播されます。
AuthenticatedPrincipalはSerializableであり、AccountImplでは安全な場所から読み込んだばかりである可能性があるため注意してください。
package poaBankSecureOld; import java.io.File; import org.omg.CORBA.ORB; import org.omg.CORBA.INTERNAL; import org.omg.CORBA.INITIALIZE; import org.omg.CORBA.PERSIST_STORE; import poaBank.AccountPOA; import poaBank.AccountPackage.InsufficientFunds; import com.sssw.jbroker.api.security.Authenticator; import com.sssw.jbroker.api.security.SecurityCurrent; import com.sssw.jbroker.api.security.SecurityException; import com.sssw.jbroker.api.security.AuthenticationScheme; import com.sssw.jbroker.api.security.AuthenticatedPrincipal; public class AccountImpl extends AccountPOA { ORB _orb; AccountBalances _accountsDb; SecurityCurrent _securityCurrent; AuthenticatedPrincipal _principal; public AccountImpl(ORB orb, File acctDb) throws Exception { | _orb = orb; | | // authenticate with the bank realm | Authenticator authenticator = (Authenticator) _orb. | resolve_initial_references("Authenticator"); | _principal = authenticator.authenticate(AuthenticationScheme.DIGEST, | "bank", "bankserver", "manager".getBytes()); | | // get the Security current | _securityCurrent = (SecurityCurrent) _orb.resolve_initial_references( | "SecurityCurrent"); | | // create the account Db | _accountsDb = new AccountBalances(acctDb, _securityCurrent); } private AccountRecord getAccount(int acctNum) { | try { | | try { | | | _securityCurrent.stackThreadPrincipal(_principal); | | | return _accountsDb.getAccount(acctNum); | | } finally { | | | _securityCurrent.unstackThreadPrincipal(_principal); | | } | } catch (SecurityException ex) { | | ex.printStackTrace(); | | throw new INTERNAL(); | } } public float deposit(float sum) { | int acctNum = getAccountNumber(); | | AccountRecord record = getAccount(acctNum); | | float balance = 0; | synchronized (record) { | | balance = record.getBalance() + sum; | | record.setBalance(balance); | } | | return balance; } public float withdraw(float sum) throws InsufficientFunds { | int acctNum = getAccountNumber(); | | AccountRecord record = getAccount(acctNum); | | float balance = 0; | synchronized (record) { | | balance = record.getBalance(); | | if ((balance - sum) < 0) | | throw new InsufficientFunds(); | | balance -= sum; | | record.setBalance(balance); | } | | return balance; } public float balance() { | return getAccount(getAccountNumber()).getBalance(); } private int getAccountNumber() { | return _object_id()[0] & 0x000000FF; } }
5.1 Account Balances
getAccountメソッドは、呼び出し側が「Bank」レルムの「bankserver」であることをチェックします。package poaBankSecureOld; import java.io.File; import java.util.Hashtable; import org.omg.CORBA.NO_PERMISSION; import com.sssw.jbroker.api.security.SecurityCurrent; import com.sssw.jbroker.api.security.SecurityException; import com.sssw.jbroker.api.security.AuthenticatedPrincipal; // Datastore for Account Balances class AccountBalances { File _dbDir; Hashtable _table; SecurityCurrent _current; AccountBalances(File dbDir, SecurityCurrent current) { | _dbDir = dbDir; | _table = new Hashtable(19); | _current = current; } synchronized AccountRecord getAccount(int acctNum) { | // verify the caller is bank server | if (!_current.getPrincipal().getName().equals("bankserver@bank")) | throw new NO_PERMISSION(); | | Integer AcctNum = new Integer(acctNum); | | AccountRecord record = (AccountRecord) _table.get(AcctNum); | | if (record == null) { | | record = new AccountRecord(0, new File(_dbDir, | | AcctNum.toString())); | | _table.put(AcctNum, record); | } | | return record; } }5.2 Account Record
package poaBankSecureOld; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import org.omg.CORBA.PERSIST_STORE; class AccountRecord { private float _balance; private File _file; AccountRecord(float balance, File file) { | _file = file; | _balance = balance; | | // if file exists read balance | if (_file.exists()) { | | try { | | | FileInputStream fis = new FileInputStream(_file); | | | ObjectInputStream ois = new ObjectInputStream(fis); | | | _balance = ((Float) ois.readObject()).floatValue(); | | | ois.close(); | | } catch (Exception ex) { | | | throw new PERSIST_STORE(); | | } | } } float getBalance() { | return _balance; } void setBalance(float balance) { | _balance = balance; | | try { | | FileOutputStream fos = new FileOutputStream(_file); | | ObjectOutputStream oos = new ObjectOutputStream(fos); | | oos.writeObject(new Float(_balance)); | | oos.close(); | } catch (Exception ex) { | | throw new PERSIST_STORE(); | } } }
server.main=poaBankSecureOld.Server server.alias=secureBankOld server.classpath=/usr/local/JBroker/examples/lib server.args=/usr/local/JBroker/examples/src/poaBankSecureOld/db server.vmflags=-DORBUseDoors=true
クライアントはユーザから取得したアカウント番号およびPINを使用して自身を認証し、ORBレベルで認証されたプリンシパルを設定します。クライアントが複数のスレッドを開始している場合、同じ識別ですべて実行されていることになります。
package poaBankSecureOld; import java.io.BufferedReader; import java.io.InputStreamReader; import java.util.StringTokenizer; import org.omg.CORBA.ORB; import org.omg.CosNaming.NameComponent; import org.omg.CosNaming.NamingContext; import org.omg.CosNaming.NamingContextHelper; import com.sssw.jbroker.api.security.Authenticator; import com.sssw.jbroker.api.security.SecurityCurrent; import com.sssw.jbroker.api.security.AuthenticationScheme; import com.sssw.jbroker.api.security.AuthenticatedPrincipal; import poaBank.Bank; import poaBank.Account; import poaBank.BankHelper; import poaBank.AccountPackage.InsufficientFunds; public class Client { ORB _orb; Bank _bank; Account _account; String _acctNum; String _acctPIN; public static void main(String[] args) { | try { | | new Client().run(args); | } catch (Exception ex) { | | ex.printStackTrace(); | } } public void run(String[] args) throws Exception { | // create the jBroker ORB | _orb = ORB.init(args, null); | | // get the root of the NameService | NamingContext root = NamingContextHelper.narrow( | _orb.resolve_initial_references("NameService")); | | // get the bank object reference | NameComponent nc = new NameComponent(args[0], ""); | NameComponent[] name = new NameComponent[] { nc }; | _bank = BankHelper.narrow(root.resolve(name)); | | // enter the request processing loop | processCommands(); } void processCommands() throws Exception { | // create a input stream reader | BufferedReader reader = new BufferedReader(new InputStreamReader( | System.in)); | | // get the account number | System.out.print("Enter Account number: "); | System.out.flush(); | _acctNum = reader.readLine(); | | // get the account PIN | System.out.print("Enter Account PIN: "); | System.out.flush(); | _acctPIN = reader.readLine(); | | // authenticate with the bank realm | Authenticator authenticator = (Authenticator) _orb. | resolve_initial_references("Authenticator"); | AuthenticatedPrincipal principal = authenticator.authenticate( | AuthenticationScheme.DIGEST, "bank", _acctNum, _acctPIN.getBytes()); | | // set the authenticated principal at the ORB level | SecurityCurrent current = (SecurityCurrent) _orb. | resolve_initial_references("SecurityCurrent"); | current.setORBPrincipal(principal); | | // get the account object | _account = _bank.getAccount(new Integer(_acctNum).intValue()); | | // enter the read-execute loop | while (true) { | | System.out.print("bank > "); | | executeCommand(readCommandLine(reader)); | } } void executeCommand(String[] command) throws Exception { | if (command.length == 0) | printHelp(); | | // get balance | else if (command[0].equals("b")) | System.out.println("\tbalance: $" + _account.balance()); | | // check the command for addition parameter | else if (command[0].equals("d")) { | | if (command.length != 2) printHelp(); | | else System.out.println("\tbalance: $"+ _account.deposit(new Float( | | command[1]).floatValue())); | } | | // deposit money | else if (command[0].equals("w")) { | | if (command.length != 2) printHelp(); | | else { | | | try { | | | | System.out.println("\tbalance: $"+ _account.withdraw( | | | | new Float(command[1]).floatValue())); | | | } catch (InsufficientFunds ex) { | | | | System.out.println("\tInsufficient Funds!"); | | | } | | } | } | | // quit | else if (command[0].equals("q")) { | | System.exit(0); | } | | // print help | else printHelp(); } void printHelp() { | System.out.println(); | System.out.println("\tCommands:"); | System.out.println("\t b // get balance"); | System.out.println("\t d <sum> // deposit sum"); | System.out.println("\t w <sum> // withdraw sum"); | System.out.println("\t q // quit"); | System.out.println(); } String[] readCommandLine(BufferedReader reader) throws Exception { | int i=0; | | String line = reader.readLine(); | | if (line == null) System.exit(0); | | StringTokenizer tokenizer = new StringTokenizer(line); | String[] command = new String[tokenizer.countTokens()]; | while (tokenizer.hasMoreTokens()) { | | command[i++] = tokenizer.nextToken(); | } | | return command; } }
Copyright © 2000-2003, Novell, Inc.All rights reserved. |