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 poaBankSecure;
import util.Util;
import org.omg.CORBA.Any;
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.security.QualityOfProtection;
import com.sssw.jbroker.api.security.CSIv2.ClientAuthInfo;
import com.sssw.jbroker.api.security.CSIv2.SecurityPolicy;
import com.sssw.jbroker.api.security.CSIv2.SecurityCurrent;
import com.sssw.jbroker.api.security.CSIv2.SecurityPolicyValue;
import com.sssw.jbroker.api.security.CSIv2.Authenticator;
import com.sssw.jbroker.api.security.CSIv2.IdentityToken;
import com.sssw.jbroker.api.security.CSIv2.InitialContextToken;
import org.omg.PortableServer.POA;
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");
| |
| | // get the security current
| | SecurityCurrent secCurrent = (SecurityCurrent) orb.
| | resolve_initial_references("SecurityCurrent");
| |
| | // set an authenticator
| | secCurrent.setAuthenticator(new Authenticator() {
| | | public int authenticate(InitialContextToken initCtxToken) {
| | | | System.out.println("user = " + initCtxToken.getUserName());
| | | | System.out.println("password = " + initCtxToken.
| | | | getPassword());
| | | | System.out.println("realm = " + initCtxToken.getRealm());
| | | | return Authenticator.SUCCESS;
| | | }
| | | public boolean assertIdentity(IdentityToken identityToken)
| | | { return true; }
| | });
| |
| | // create the CSIv2 security Policy
| | Any any = orb.create_any();
| | any.insert_Value(new SecurityPolicyValue(null, new ClientAuthInfo(
| | "bank", false), true));
| | SecurityPolicy secPolicy = (SecurityPolicy) orb.create_policy(
| | SecurityPolicy.POLICY_TYPE, any);
| |
| | // 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),
| | | secPolicy,
| | });
| |
| | // 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("secureBank", "");
| | 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 poaBankSecure;
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.CSIv2.SecurityPolicy;
import com.sssw.jbroker.api.security.CSIv2.SecurityCurrent;
import poaBank.BankPOA;
import poaBank.Account;
import poaBank.AccountHelper;
import poaBank.BankPackage.noSuchAccount;
public 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("IP = " + _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;
}
}
この例では、AccountデータストアがローカルのJavaオブジェクトです。Accountデータストアがリモートオブジェクトである場合(別の場所で実行されている可能性があります)、識別「bankserver」がそれに伝播されます。
package poaBankSecure;
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.SecurityException;
import com.sssw.jbroker.api.security.CSIv2.IdentityToken;
import com.sssw.jbroker.api.security.CSIv2.SecurityContext;
import com.sssw.jbroker.api.security.CSIv2.SecurityCurrent;
public class AccountImpl extends AccountPOA
{
ORB _orb;
AccountBalances _accountsDb;
SecurityCurrent _securityCurrent;
SecurityContext _bankServerCtx;
public AccountImpl(ORB orb, File acctDb) throws Exception
{
| _orb = orb;
|
| // get the SecurityCurrent
| _securityCurrent = (SecurityCurrent) orb.
| resolve_initial_references("SecurityCurrent");
|
| // create a security context
| _bankServerCtx = _securityCurrent.newContext();
| _bankServerCtx.setIdentityToken(_securityCurrent.createIdentityToken(
| "bankserver", "bank"));
|
| // create the account Db
| _accountsDb = new AccountBalances(acctDb, _securityCurrent);
}
private AccountRecord getAccount(int acctNum)
{
| try {
| | try {
| | | _securityCurrent.stackThreadContext(_bankServerCtx);
| | |
| | | return _accountsDb.getAccount(acctNum);
| | |
| | } finally {
| | | _securityCurrent.unstackThreadContext(_bankServerCtx);
| | }
| |
| } 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 poaBankSecure; import java.io.File; import java.util.Hashtable; import org.omg.CORBA.NO_PERMISSION; import com.sssw.jbroker.api.security.SecurityException; import com.sssw.jbroker.api.security.CSIv2.SecurityContext; import com.sssw.jbroker.api.security.CSIv2.SecurityCurrent; // 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) throws SecurityException { | // verify the caller | if (!_current.getCaller().getIdentityToken("bank").getUser(). | equals("bankserver")) 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 poaBankSecure; 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=poaBankSecure.Server server.alias=secureBank server.classpath=/usr/local/JBroker/examples/lib server.args=/usr/local/JBroker/examples/src/poaBankSecure/db server.vmflags=-DORBDebug=true
クライアントはユーザから取得したアカウント番号およびPINを使用して自身を認証し、ORBレベルで認証されたプリンシパルを設定します。クライアントが複数のスレッドを開始している場合、同じ識別ですべて実行されていることになります。
package poaBankSecure;
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.CSIv2.AuthCallback;
import com.sssw.jbroker.api.security.CSIv2.SecurityContext;
import com.sssw.jbroker.api.security.CSIv2.SecurityCurrent;
import com.sssw.jbroker.api.security.CSIv2.InitialContextToken;
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();
|
| // get the security current
| SecurityCurrent secCurrent = (SecurityCurrent) _orb.
| resolve_initial_references("SecurityCurrent");
|
| // set up the security context
| SecurityContext secContext = secCurrent.newContext();
| secContext.setInitialContextToken(secCurrent.createInitialContextToken(
| _acctNum, _acctPIN, "bank"));
| secCurrent.setORBContext(secContext);
|
| // 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. |