[急]关于精通EJB3.0中stand-alone客户端通过JAAS无法访问授权组件的问题

Barryzhong 2008-06-20 11:59:39
==============================================

实验环境如下:

同一台电脑: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();

}

}

}


...全文
252 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
Barryzhong 2008-06-23
  • 打赏
  • 举报
回复
csdn上的Java高手都干啥去了?


都离开csdn了?


怎么这么个基础的问题都没人回答呢?


难道是我人品太差?


Shit!!
nec_7788 2008-06-23
  • 打赏
  • 举报
回复
Barryzhong 2008-06-22
  • 打赏
  • 举报
回复
那位大虾能够指点一下?


郁闷中........
nec_5499 2008-06-21
  • 打赏
  • 举报
回复
Barryzhong 2008-06-20
  • 打赏
  • 举报
回复
异常堆栈:
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 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.corba.ee.impl.javax.rmi.CORBA.Util.mapSystemException(Util.ja

va:277)

at com.sun.corba.ee.impl.presentation.rmi.StubInvocationHandlerImpl.priv

ateInvoke(StubInvocationHandlerImpl.java:205)

at com.sun.corba.ee.impl.presentation.rmi.StubInvocationHandlerImpl.invo

ke(StubInvocationHandlerImpl.java:152)

at com.sun.corba.ee.impl.presentation.rmi.bcel.BCELStubBase.invoke(BCELS

tubBase.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 more

Caused 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_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)
Barryzhong 2008-06-20
  • 打赏
  • 举报
回复
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
Barryzhong 2008-06-20
  • 打赏
  • 举报
回复
JAAS相关类:

CallbackHandler.java

package 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;
}
}

67,513

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧