[急]关于精通EJB3.0中stand-alone客户端通过JAAS无法访问授权组件的问题
==============================================
实验环境如下:
同一台电脑:localhost
操作系统:WindowsXP
JavaEE服务器:Glassfish V2
JDK:1.6.0_05
开发工具:netbean | Eclipse
EJB netbean工程附件:converter-secure.zip
Client 工程附件: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:barry
Group:user
Password:xxxxx
如图所示:
服务器端domain安全配置文件:如附件login.conf,安全策略文件:server.policy
服务器端EJB程序如下:
业务接口:Converter.java
package converter.secure.ejb;
import java.math.BigDecimal;
import javax.ejb.Remote;
@Remote
public interface Converter {
public BigDecimal dollarToYen(BigDecimal dollars);
public BigDecimal yenToEuro(BigDecimal yen);
}
Bean类:ConverterBean.java
package 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.java
package 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();
}
}
}