3/26/08


J2EE Security with WebLogic 9.2.1 Part 2. EJB


Let's consider enterprise bean (EJB 2.1 with WebLogic annotations):

import java.util.Calendar;
import javax.ejb.SessionBean;
import weblogic.ejb.GenericSessionBean;
import weblogic.ejbgen.RemoteMethod;
import weblogic.ejbgen.Session;
import weblogic.ejbgen.JndiName;
import weblogic.ejbgen.FileGeneration;
import weblogic.ejbgen.Constants;
import weblogic.ejbgen.RoleMappings;
import weblogic.ejbgen.RoleMapping;

@Session(ejbName = "MyBean")
@RoleMappings(value={@RoleMapping(principals = "alex", roleName = "admin")})
@JndiName(remote = "ejb.MyBeanRemoteHome")
@FileGeneration(remoteClass = Constants.Bool.TRUE, remoteHome = Constants.Bool.TRUE, localClass = Constants.Bool.FALSE, localHome = Constants.Bool.FALSE)

public class MyBean extends GenericSessionBean implements SessionBean {
private static final long serialVersionUID = 1L;

public void ejbCreate() { }

@RemoteMethod(roles="admin")
public String getDate() {
System.out.println(getSessionContext().getCallerPrincipal().getName());
return "Date from ejb is: " + Calendar.getInstance().getTime().toString();
}
}


Also user alex should be created in Web Logic Server console for default realm. Let's try to invoke that bean from next code:

Hashtable env = new Hashtable();

env.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
env.put(Context.SECURITY_PRINCIPAL, "weblogic");
env.put(Context.SECURITY_CREDENTIALS, "weblogic");
env.put(Context.PROVIDER_URL, "t3://localhost:7001");

Context ct = new InitialContext(env);
Object homeObject = ct.lookup("ejb.MyBeanRemoteHome");
MyBeanRemoteHome home = (MyBeanRemoteHome) PortableRemoteObject.narrow( homeObject, MyBeanRemoteHome.class);
System.out.println(home.create().getDate());


The result is: java.rmi.AccessException: [EJB:010160]Security Violation: User: 'weblogic' has insufficient permission to access EJB...

(Also we can use next code to retrieve Initial Context:
weblogic.jndi.Environment env = new Environment();
env.setProviderUrl("t3://localhost:7001");
env.setInitialContextFactory("weblogic.jndi.WLInitialContextFactory");
env.setSecurityPrincipal("alex");
env.setSecurityCredentials( "weblogic");
javax.naming.InitialContext ct = new InitialContext(env.getInitialContext().getEnvironment());)

Let's replace env.put(Context.SECURITY_PRINCIPAL, "weblogic") to env.put(Context.SECURITY_PRINCIPAL, "alex"). The result is Ok.

Let's do:

//env.put(Context.SECURITY_PRINCIPAL, "alex");
//env.put(Context.SECURITY_CREDENTIALS, "weblogic");

The result is: Security Violation: User: 'anonymous' has insufficient permission to access EJB..

Let's use JAAS:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.PrivilegedAction;
import java.util.Hashtable;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.rmi.PortableRemoteObject;
import javax.security.auth.login.*;
import com.MyBeanRemoteHome;
import weblogic.security.Security;

public class Main {
public static void main(String[] args) throws Exception {
LoginContext loginContext = null;
loginContext = new LoginContext("Sample", new SampleCallbackHandler("alex", "weblogic", "t3://localhost:7001"));
loginContext.login();
Security.runAs(loginContext.getSubject(), new EjbInvocation());
return;
}

public static class EjbInvocation implements PrivilegedAction {
public Object run() {
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
env.put(Context.PROVIDER_URL, "t3://localhost:7001");
Context ct = new InitialContext(env);
Object homeObject = ct.lookup("ejb.MyBeanRemoteHome");
MyBeanRemoteHome home = (MyBeanRemoteHome) PortableRemoteObject.narrow( homeObject, MyBeanRemoteHome.class);
System.out.println(home.create().getDate());
return null;
}
}
}


Now it's okay too.

Next part of research is accessing EJB from secured servlet described in previous post. Servlet and EJB belong to one Realm. Servlet just contain code in service method:

Hashtable env = new Hashtable();
env.putContext.INITIAL_CONTEXT_FACTORY,"weblogic.jndi.WLInitialContextFactory");
env.put(Context.PROVIDER_URL, "t3://localhost:7001");
Object homeObject = new InitialContext(env).lookup("ejb.MyBeanRemoteHome");
MyBeanRemoteHome home = (MyBeanRemoteHome) PortableRemoteObject.narrow(homeObject, MyBeanRemoteHome.class);
home.create().getDate();

So access to that sarvlet can be done only by authenticated user. Let's try to access as weblogic user. Result is: Security Violation: User: 'weblogic' has insufficient permission to access EJB:..
Nice! Next login as alex user. Result is Ok (ejb method returned string successfuly). Great. Servlet accesseb EJB with account of user that has been invoking the servlet.

No comments: