==============================================实验环境如下:同一台电脑:localhost操作系统:WindowsXPJavaEE服务器:Glassfish V2JDK:1.6.0_05开发工具:netbean | EclipseEJB netbean工程附件:converter-secure.zipClient 工程附件:SecurityClient.zip===============================================客户端安全策略文件Client.policy如下: grant {    permission javax.security.auth.AuthPermission "createLoginContext.HelloClient";    permission javax.security.auth.AuthPermission "modifyPrivateCredentials";}; 客户端安全配置文件Client.config文件如下:default {         com.sun.enterprise.security.auth.login.ClientPasswordLoginModule required debug=false;}; HelloClient {         madz.vicp.net.PasswordLoginModule required debug=false;}; certificate {         com.sun.enterprise.security.auth.login.ClientCertificateLoginModule required debug=false;};服务器端安全配置如下:Security > Realms > file:Username:barryGroup:userPassword:xxxxx如图所示:服务器端domain安全配置文件:如附件login.conf,安全策略文件:server.policy服务器端EJB程序如下:业务接口:Converter.java package converter.secure.ejb; import java.math.BigDecimal;import javax.ejb.Remote;  @Remotepublic interface Converter {    public BigDecimal dollarToYen(BigDecimal dollars);     public BigDecimal yenToEuro(BigDecimal yen);}Bean类:ConverterBean.javapackage converter.secure.ejb; import java.math.BigDecimal;import javax.ejb.*;import java.security.Principal;import javax.annotation.Resource;import javax.ejb.SessionContext;import javax.annotation.security.RolesAllowed;import javax.annotation.security.DeclareRoles;  /** * This is the bean class for the ConverterBean enterprise bean. * Created Jan 20, 2006 1:14:27 PM * @author ian */@Stateless@DeclareRoles("BeanUser")public class ConverterBean implements converter.secure.ejb.Converter {    @Resource    SessionContext ctx;    private BigDecimal euroRate = new BigDecimal("0.0071");    private BigDecimal yenRate = new BigDecimal("115.3100");     @RolesAllowed("BeanUser")    public BigDecimal dollarToYen(BigDecimal dollars) {        BigDecimal result = new BigDecimal("0.0");        Principal callerPrincipal = ctx.getCallerPrincipal();         if (ctx.isCallerInRole("BeanUser")) {            result = dollars.multiply(yenRate);             return result.setScale(2, BigDecimal.ROUND_UP);        } else {            return result.setScale(2, BigDecimal.ROUND_UP);        }    }     @RolesAllowed("BeanUser")    public BigDecimal yenToEuro(BigDecimal yen) {        BigDecimal result = new BigDecimal("0.0");        Principal callerPrincipal = ctx.getCallerPrincipal();         if (ctx.isCallerInRole("BeanUser")) {            result = yen.multiply(euroRate);             return result.setScale(2, BigDecimal.ROUND_UP);        } else {            return result.setScale(2, BigDecimal.ROUND_UP);        }    }}服务器端配置文件:sun-ejb-jar.xml<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE sun-ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Application Server 9.0 EJB 3.0//EN" "http://www.sun.com/software/appserver/dtds/sun-ejb-jar_3_0-0.dtd"><sun-ejb-jar>  <security-role-mapping>    <role-name>BeanUser</role-name>    <group-name>user</group-name>  </security-role-mapping>  <enterprise-beans>    <unique-id>0</unique-id>    <ejb>      <ejb-name>ConverterBean</ejb-name>      <jndi-name>ConverterBean</jndi-name>      <pass-by-reference>false</pass-by-reference>      <ior-security-config>        <transport-config>          <integrity>supported</integrity>          <confidentiality>supported</confidentiality>          <establish-trust-in-target>supported</establish-trust-in-target>          <establish-trust-in-client>supported</establish-trust-in-client>        </transport-config>        <as-context>          <auth-method>username_password</auth-method>          <realm>file</realm>          <required>true</required>        </as-context>        <sas-context>          <caller-propagation>supported</caller-propagation>        </sas-context>      </ior-security-config>      <is-read-only-bean>false</is-read-only-bean>      <refresh-period-in-seconds>-1</refresh-period-in-seconds>      <gen-classes/>    </ejb>    <ejb>      <ejb-name>HelloWorldBean</ejb-name>      <jndi-name>HelloWorldBean</jndi-name>    </ejb>  </enterprise-beans></sun-ejb-jar>上述配置,在使用Application Client的时候可以通过容器提供的登陆框,使用barry:1q2w3e4r5t进行访问。可是单独客户端却无法通过。客户端程序如下: 主程序:Main.javapackage SecurityClient; import converter.secure.ejb.Converter;import java.math.BigDecimal;import java.util.Properties;import java.util.logging.Level;import java.util.logging.Logger;import javax.naming.InitialContext;import javax.naming.NamingException;import javax.security.auth.login.LoginContext;import javax.security.auth.login.LoginException;import madz.vicp.net.CallbackHandler;import madz.vicp.net.HelloWorldRemote; /** * * @author djzhong */public class Main {     private static Converter converter;//    private static HelloWorldRemote helloWorld;     /**     * @param args the command line arguments     */    public static void main(String[] args) {        try {            // TODO code application logic here            System.out.println("Starting login modules ...");            LoginContext loginContext = new LoginContext("HelloClient", new CallbackHandler());            loginContext.login();            System.out.println("Login passed @ client module ...");                        Main client = new Main();            Properties p = new Properties();            p.put("org.omg.CORBA.ORBInitialHost", "localhost");            p.put("org.omg.CORBA.ORBInitialPort", "3700");            InitialContext ctx = new InitialContext();            converter = (Converter) ctx.lookup("ConverterBean");                        client.doConversion();        } catch (LoginException ex) {            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);        } catch (NamingException ex) {            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);        }    }     public void doConversion() {        try {            BigDecimal param = new BigDecimal("100.00");            BigDecimal yenAmount = converter.dollarToYen(param);             System.out.println("$" + param + " is " + yenAmount + " Yen.");             BigDecimal euroAmount = converter.yenToEuro(yenAmount);            System.out.println(yenAmount + " Yen is " + euroAmount + " Euro.");             System.exit(0);        } catch (Exception ex) {            System.err.println("Caught an unexpected exception!");            ex.printStackTrace();        }    }}

解决方案 »

  1.   

    JAAS相关类:CallbackHandler.javapackage madz.vicp.net; import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import javax.security.auth.callback.Callback;import javax.security.auth.callback.NameCallback;import javax.security.auth.callback.PasswordCallback;import javax.security.auth.callback.UnsupportedCallbackException; /** * * @author djzhong */public class CallbackHandler implements javax.security.auth.callback.CallbackHandler {     public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {        System.out.println("CallbackHandler handling  ...");        for (int i = 0; i < callbacks.length; i++) {            if (callbacks[i] instanceof NameCallback) {                NameCallback nc = (NameCallback) callbacks[i];                System.out.println(nc.getPrompt());                String name = (new BufferedReader(new InputStreamReader(System.in))).readLine();                nc.setName(name);            } else if (callbacks[i] instanceof PasswordCallback) {                PasswordCallback pc = (PasswordCallback) callbacks[i];                System.out.println(pc.getPrompt());                String password = (new BufferedReader(new InputStreamReader(System.in))).readLine();                pc.setPassword(password.toCharArray());            } else{                throw new UnsupportedCallbackException(callbacks[i],"Unrecognized Callback");            }        }        System.out.println("CallbackHandler handled OK");    }} package madz.vicp.net; import com.sun.appserv.security.ProgrammaticLogin;import com.sun.enterprise.security.auth.login.PasswordCredential;import java.security.Principal;import java.util.Map;import javax.security.auth.Subject;import javax.security.auth.callback.Callback;import javax.security.auth.callback.CallbackHandler;import javax.security.auth.callback.NameCallback;import javax.security.auth.callback.PasswordCallback;import javax.security.auth.callback.UnsupportedCallbackException;import javax.security.auth.login.LoginException;import javax.security.auth.spi.LoginModule; /** * * @author djzhong */public class PasswordLoginModule implements LoginModule {     private boolean commitSucceeded;    private String DEFAULT_REALMNAME = "HelloRealm";    private Principal userPrincipal;    private boolean succeeded;    private String username;    private char[] password;    private Subject subject;    private CallbackHandler callbackHandler;    private Map sharedState;    private Map options;     public void initialize(Subject subject, CallbackHandler callbackHandler, Map<String, ?> sharedState, Map<String, ?> options) {        System.out.println("PasswordLoginModule initializing ...");        this.subject = subject;        this.callbackHandler = callbackHandler;        this.sharedState = sharedState;        this.options = options;        System.out.println("PasswordLoginModule initialized OK!");    }     public boolean login() throws LoginException {        System.out.println("PasswordLoginModule loginning ...");        if (callbackHandler == null) {            String failure = "login.nocallback" + "Error: no CallbackHandler available to garner authentication information from the user";            throw new LoginException(failure);        }         Callback[] callbacks = new Callback[2];        callbacks[0] = new NameCallback("username: ");        callbacks[1] = new PasswordCallback("password: ", false);         try {            callbackHandler.handle(callbacks);             username = ((NameCallback) callbacks[0]).getName();            if (username == null) {                throw new LoginException("No User Specified!");            }            char[] tmpPassword = ((PasswordCallback) callbacks[1]).getPassword();            if (tmpPassword == null) {                tmpPassword = new char[0];            }             password = new char[tmpPassword.length];            System.arraycopy(tmpPassword, 0, password, 0, tmpPassword.length);            succeeded = true;        } catch (java.io.IOException ioe) {            throw new LoginException(ioe.toString());        } catch (UnsupportedCallbackException uce) {            throw new LoginException("Error: No Callback available to collect authentication data :" + uce.getCallback().toString());        } catch (Exception e) {            e.printStackTrace();        }        System.out.println("PasswordLoginModule login OK.");        return true;    }     public boolean commit() throws LoginException {        System.out.println("PasswordLoginModule committing ...");        if (succeeded == false) {            return false;        } else {            // add a Principal (authenticated identity)            // to the Subject            System.out.println("Commit construct Principal");            // assume the user we authenticated is the PrincipalImpl            userPrincipal = new PrincipalImpl(username);            if (!subject.getPrincipals().contains(userPrincipal)) {                subject.getPrincipals().add(userPrincipal);            }             String realm = DEFAULT_REALMNAME;                        System.out.println("Commit construct PasswordCredential");            PasswordCredential pc =                    new PasswordCredential(username, new String(password), realm);             if (!subject.getPrivateCredentials().contains(pc)) {                subject.getPrivateCredentials().add(pc);            }//            ProgrammaticLogin pl = new ProgrammaticLogin();//            pl.login(username, new String(password));[c1]             System.out.println("Commit release variables");            // in any case, clean out state            username = null;            for (int i = 0; i < password.length; i++) {                password[i] = ' ';            }            password = null;            commitSucceeded = true;            System.out.println("PasswordLoginModule committed OK");            return true;        }    }     public boolean abort() throws LoginException {        System.out.println("PasswordLoginModule aborting ...");        if (succeeded == false) {            return false;        } else if (succeeded == true && commitSucceeded == false) {            // login succeeded but overall authentication failed            succeeded = false;            username = null;            if (password != null) {                for (int i = 0; i < password.length; i++) {                    password[i] = ' ';                }                password = null;            }            userPrincipal = null;        } else {            // overall authentication succeeded and commit succeeded,            
                logout();        }
            return true;
       }
        public boolean logout() throws LoginException {
            System.out.println("PasswordLoginModule logouting  ...");
            subject.getPrincipals().remove(userPrincipal);
            succeeded = false;
            succeeded = commitSucceeded;
            username = null;
            if (password != null) {
               for (int i = 0; i < password.length; i++) {
                    password[i] = ' ';
                }
                password = null;
            }
            userPrincipal = null;
            System.out.println("PasswordLoginModule logout complete!");
            return true;
        }
    }
      

  2.   

    PrincipalImpl.java
    package madz.vicp.net;import java.security.Principal;
    public class PrincipalImpl implements Principal{    private String name;     public PrincipalImpl(String name){        this.name = name;    }    public String getName() {        return this.name;    }}运行时参数:java -Djava.security.auth.login.config=E:\appclientlogin.conf -Djava.security.policy=E:\client.policy -Dorg.omg.CORBA.ORBInitial Host=localhost -Dorg.omg.CORBA.ORBInitialPort=3700 -jar SecurityClient.jar
      

  3.   

    异常堆栈:
    Starting login modules ...
    PasswordLoginModule initializing ...
    PasswordLoginModule initialized OK!
    PasswordLoginModule loginning ...
    CallbackHandler handling  ...
    username:
    barry
    password:
    xxxxxxxx
    CallbackHandler handled OK
    PasswordLoginModule login OK.
    PasswordLoginModule committing ...
    Commit construct Principal
    Commit construct PasswordCredential
    Commit release variables
    PasswordLoginModule committed OK
    Login passed @ client module ...
    2008-6-20 11:22:35 SecurityClient.Main main
    严重: null
    javax.naming.NamingException: ejb ref resolution error for remote business inter
    faceconverter.secure.ejb.Converter [Root exception is java.rmi.AccessException:
    CORBA NO_PERMISSION 0 No; nested exception is:
            org.omg.CORBA.NO_PERMISSION: ----------BEGIN server-side stack trace----
    ------
    org.omg.CORBA.NO_PERMISSION:   vmcid: 0x0  minor code: 0  completed: No
            at com.sun.enterprise.iiop.security.SecServerRequestInterceptor.handle_n
    ull_service_context(SecServerRequestInterceptor.java:406)
            at com.sun.enterprise.iiop.security.SecServerRequestInterceptor.receive_
    request(SecServerRequestInterceptor.java:428)
            at com.sun.corba.ee.impl.interceptors.InterceptorInvoker.invokeServerInt
    erceptorIntermediatePoint(InterceptorInvoker.java:627)
            at com.sun.corba.ee.impl.interceptors.PIHandlerImpl.invokeServerPIInterm
    ediatePoint(PIHandlerImpl.java:530)
            at com.sun.corba.ee.impl.protocol.CorbaServerRequestDispatcherImpl.getSe
    rvantWithPI(CorbaServerRequestDispatcherImpl.java:406)
            at com.sun.corba.ee.impl.protocol.CorbaServerRequestDispatcherImpl.dispa
    tch(CorbaServerRequestDispatcherImpl.java:224)
            at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.handleRequest
    Request(CorbaMessageMediatorImpl.java:1846)
            at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.handleRequest
    (CorbaMessageMediatorImpl.java:1706)
            at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.handleInput(C
    orbaMessageMediatorImpl.java:1088)
            at com.sun.corba.ee.impl.protocol.giopmsgheaders.RequestMessage_1_2.call
    back(RequestMessage_1_2.java:223)
            at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.handleRequest
    (CorbaMessageMediatorImpl.java:806)
            at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.dispatch(Corb
    aMessageMediatorImpl.java:563)        at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.doWork(CorbaM
    essageMediatorImpl.java:2567)
            at com.sun.corba.ee.impl.orbutil.threadpool.ThreadPoolImpl$WorkerThread.
    run(ThreadPoolImpl.java:555)
    ----------END server-side stack trace----------  vmcid: 0x0  minor code: 0  comp
    leted: No]
            at com.sun.ejb.EJBUtils.lookupRemote30BusinessObject(EJBUtils.java:367)
            at com.sun.ejb.containers.RemoteBusinessObjectFactory.getObjectInstance(
    RemoteBusinessObjectFactory.java:74)        at javax.naming.spi.NamingManager.getObjectInstance(Unknown Source)        at com.sun.enterprise.naming.SerialContext.lookup(SerialContext.java:344)        at javax.naming.InitialContext.lookup(Unknown Source)        at SecurityClient.Main.main(Main.java:44)Caused by: java.rmi.AccessException: CORBA NO_PERMISSION 0 No; nested exceptionis:        org.omg.CORBA.NO_PERMISSION: ----------BEGIN server-side stack trace----------org.omg.CORBA.NO_PERMISSION:   vmcid: 0x0  minor code: 0  completed: No        at com.sun.enterprise.iiop.security.SecServerRequestInterceptor.handle_null_service_context(SecServerRequestInterceptor.java:406)        at com.sun.enterprise.iiop.security.SecServerRequestInterceptor.receive_request(SecServerRequestInterceptor.java:428)        at com.sun.corba.ee.impl.interceptors.InterceptorInvoker.invokeServerInterceptorIntermediatePoint(InterceptorInvoker.java:627)        at com.sun.corba.ee.impl.interceptors.PIHandlerImpl.invokeServerPIIntermediatePoint(PIHandlerImpl.java:530)        at com.sun.corba.ee.impl.protocol.CorbaServerRequestDispatcherImpl.getServantWithPI(CorbaServerRequestDispatcherImpl.java:406)        at com.sun.corba.ee.impl.protocol.CorbaServerRequestDispatcherImpl.dispatch(CorbaServerRequestDispatcherImpl.java:224)        at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.handleRequestRequest(CorbaMessageMediatorImpl.java:1846)        at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.handleRequest(CorbaMessageMediatorImpl.java:1706)        at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.handleInput(CorbaMessageMediatorImpl.java:1088)        at com.sun.corba.ee.impl.protocol.giopmsgheaders.RequestMessage_1_2.callback(RequestMessage_1_2.java:223)        at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.handleRequest(CorbaMessageMediatorImpl.java:806)        at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.dispatch(CorbaMessageMediatorImpl.java:563)        at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.doWork(CorbaMessageMediatorImpl.java:2567)        at com.sun.corba.ee.impl.orbutil.threadpool.ThreadPoolImpl$WorkerThread.run(ThreadPoolImpl.java:555) ----------END server-side stack trace----------  vmcid: 0x0  minor code: 0  completed: No        at com.sun.corba.ee.impl.javax.rmi.CORBA.Util.mapSystemException(Util.java:277)        at com.sun.corba.ee.impl.presentation.rmi.StubInvocationHandlerImpl.privateInvoke(StubInvocationHandlerImpl.java:205)        at com.sun.corba.ee.impl.presentation.rmi.StubInvocationHandlerImpl.invoke(StubInvocationHandlerImpl.java:152)        at com.sun.corba.ee.impl.presentation.rmi.bcel.BCELStubBase.invoke(BCELStubBase.java:225)        at com.sun.ejb.codegen._GenericEJBHome_Generated_DynamicStub.create(com/sun/ejb/codegen/_GenericEJBHome_Generated_DynamicStub.java)        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)        at java.lang.reflect.Method.invoke(Unknown Source)        at com.sun.ejb.EJBUtils.lookupRemote30BusinessObject(EJBUtils.java:359)        ... 5 moreCaused by: org.omg.CORBA.NO_PERMISSION: ----------BEGIN server-side stack trace----------org.omg.CORBA.NO_PERMISSION:   vmcid: 0x0  minor code: 0  completed: No        at com.sun.enterprise.iiop.security.SecServerRequestInterceptor.handle_null_service_context(SecServerRequestInterceptor.java:406)        at com.sun.enterprise.iiop.security.SecServerRequestInterceptor.receive_request(SecServerRequestInterceptor.java:428)        at com.sun.corba.ee.impl.interceptors.InterceptorInvoker.invokeServerInterceptorIntermediatePoint(InterceptorInvoker.java:627)        at com.sun.corba.ee.impl.interceptors.PIHandlerImpl.invokeServerPIIntermediatePoint(PIHandlerImpl.java:530)        at com.sun.corba.ee.impl.protocol.CorbaServerRequestDispatcherImpl.getServantWithPI(CorbaServerRequestDispatcherImpl.java:406)        at com.sun.corba.ee.impl.protocol.CorbaServerRequestDispatcherImpl.dispatch(CorbaServerRequestDispatcherImpl.java:224)        at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.handleRequestRequest(CorbaMessageMediatorImpl.java:1846)        at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.handleRequest(CorbaMessageMediatorImpl.java:1706)        at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.handleInput(CorbaMessageMediatorImpl.java:1088)        at com.sun.corba.ee.impl.protocol.giopmsgheaders.RequestMessage_1_2.callback(RequestMessage_1_2.java:223)
      

  4.   

    csdn上的Java高手都干啥去了?
    都离开csdn了?
    怎么这么个基础的问题都没人回答呢?
    难道是我人品太差?
    Shit!!