Dùng java authentication & authorization services(jaas) cấu hình phân quyền sử dụng các bussiness methods trong ejb
A. Tạo EJB
1. Tạo thư mục example1 để lưu tất cả vào đấy
2. Tạo Session Beans Remote Interface:
package ejb.jaas;
import java.rmi.RemoteException; import javax.ejb.EJBObject; public interface Session extends EJBObject { public String echo(String arg) throws RemoteException; public void noop() throws RemoteException; } |
3. Tạo Session Beans Home Interface
package ejb.jaas;
import java.rmi.RemoteException; import javax.ejb.CreateException; import javax.ejb.EJBHome; public interface SessionHome extends EJBHome { public Session create() throws RemoteException, CreateException; } |
4. Tạo Stateless Session Bean
package ejb.jaas;
import java.security.Principal; import javax.ejb.CreateException; import javax.ejb.SessionBean; import javax.ejb.SessionContext; /** @ejbHome: SessionHome @ejbRemote: Session */ public class StatelessSessionBean implements SessionBean { private SessionContext sessionContext; public StatelessSessionBean(){ } public void ejbCreate() throws CreateException { System.out.println(“StatelessSessionBean.ejbCreate() called”); } public void ejbActivate() { System.out.println(“StatelessSessionBean.ejbActivate() called”); } public void ejbPassivate() { System.out.println(“StatelessSessionBean.ejbPassivate() called”); } public void ejbRemove() { System.out.println(“StatelessSessionBean.ejbRemove() called”); } public void setSessionContext(SessionContext context) { sessionContext = context; } public String echo(String arg) { System.out.println(“StatelessSessionBean.echo, arg=”+arg); Principal p = sessionContext.getCallerPrincipal(); System.out.println(“StatelessSessionBean.echo, callerPrincipal=”+p); return arg; } public void noop() { System.out.println(“StatelessSessionBean.noop”); Principal p = sessionContext.getCallerPrincipal(); System.out.println(“StatelessSessionBean.noop, callerPrincipal=”+p); } } |
5. Tạo Stateful Session Bean
package ejb.jaas;
import java.security.Principal; import javax.ejb.CreateException; import javax.ejb.SessionBean; import javax.ejb.SessionContext; /** @ejbHome: SessionHome @ejbRemote: Session */ public class StatefulSessionBean implements SessionBean { private SessionContext sessionContext; public void ejbCreate() throws CreateException { System.out.println(“StatefulSessionBean.ejbCreate() called”); } public void ejbActivate() { System.out.println(“StatefulSessionBean.ejbActivate() called”); } public void ejbPassivate() { System.out.println(“StatefulSessionBean.ejbPassivate() called”); } public void ejbRemove() { System.out.println(“StatefulSessionBean.ejbRemove() called”); } public void setSessionContext(SessionContext context) { sessionContext = context; } public String echo(String arg) { System.out.println(“StatefulSessionBean.echo, arg=”+arg); Principal p = sessionContext.getCallerPrincipal(); System.out.println(“StatefulSessionBean.echo, callerPrincipal=”+p); return arg; } public void noop() { System.out.println(“StatefulSessionBean.noop”); Principal p = sessionContext.getCallerPrincipal(); System.out.println(“StatefulSessionBean.noop, callerPrincipal=”+p); } } |
B. Cấu hình triển khai EJB
1. Tạo ejb-jar.xml Deployment Descriptor trong thư mục META-INF
<?xml version=”1.0″ encoding=”UTF-8″?>
<!DOCTYPE ejb-jar PUBLIC “-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 1.1//EN” “http://java.sun.com/j2ee/dtds/ejb-jar_1_1.dtd”> <ejb-jar> <display-name>SecurityTests</display-name> <enterprise-beans> <session> <description>A trival stateless session echo bean</description> <ejb-name>StatelessSession</ejb-name> <home>ejb.jaas.SessionHome</home> <remote>ejb.jaas.Session</remote> <ejb-class>ejb.jaas.StatelessSessionBean</ejb-class> <session-type>Stateless</session-type> <transaction-type>Container</transaction-type> </session> <session> <description>A trival stateful session echo bean</description> <ejb-name>StatefulSession</ejb-name> <home>ejb.jaas.SessionHome</home> <remote>ejb.jaas.Session</remote> <ejb-class>ejb.jaas.StatefulSessionBean</ejb-class> <session-type>Stateful</session-type> <transaction-type>Container</transaction-type> </session> </enterprise-beans> <assembly-descriptor> <security-role> <role-name>Echo</role-name> </security-role> <method-permission> <role-name>Echo</role-name> <method> <ejb-name>StatelessSession</ejb-name> <method-name>*</method-name> </method> <method> <ejb-name>StatefulSession</ejb-name> <method-name>*</method-name> </method> </method-permission> <method-permission> <role-name>Coder</role-name> <method> <ejb-name>StatefulSession</ejb-name> <method-name>create</method-name> </method> <method> <ejb-name>StatefulSession</ejb-name> <method-name>remove</method-name> </method> <method> <ejb-name>StatefulSession</ejb-name> <method-name>noop</method-name> </method> </method-permission> </assembly-descriptor> </ejb-jar> |
2. Tạo jboss.xml Deployment Descriptor trong thư mục META-INF
<?xml version=”1.0″ encoding=”UTF-8″?>
<jboss> <!– All bean containers use this security manager by default –> <security-domain>java:/jaas/example1</security-domain> <enterprise-beans> <session> <ejb-name>StatelessSession</ejb-name> <jndi-name>example1/StatelessSession</jndi-name> </session> <session> <ejb-name>StatefulSession</ejb-name> <jndi-name>example1/StatefulSession</jndi-name> </session> </enterprise-beans> </jboss> |
3. Tạo file users.properties có nội dung:
#dinh dang : <username>=<password>
scott=echoman stark=javaman |
File này khai báo với JBOSS username và password của chương trình sẽ được lookup ở đây.
4. Tạo file roles.properties có nội dung
#dinh dang : username=role1[,role2,…]
scott=Echo,Coder stark=Coder |
File này khai báo các roles mà user có thể sử dụng được. Như vậy, scott sẽ sử dụng được 2 roles là Echo và Coder, stark sẽ sử dụng được role Coder
Chú ý trong file ejb-jar.xml ở thẻ <assembly-descriptor>. Điều đó có nghĩa là role Echo sẽ sử dụng được tất cả các phương thức trong StatelessSessionBean cũng như StatefulSessionBean. Còn role Coder chỉ sử dụng được 3 phương thức create, remove và noop trong StatefulSessionBean
Copy 2 files này vào thư mục %JBOSS_HOME%\server\default\conf\
5. Tạo file auth.conf có nội dung
example1 {
// properties file LoginModule ho tro cho ánh xa CallerPrincipal org.jboss.security.auth.spi.UsersRolesLoginModule required ; }; |
Copy file này vào thư mục %JBOSS_HOME%\conf\default\
6. Tạo file compile.bat có nội dung:
javac -d . *.java
pause |
Chạy file này để biên dịch các tập tin. Phải đảm bảo việc biên dịch là OK.
7. Tạo file createJar.bat có nội dung
jar cvf JAAS_Example1.jar ejb/jaas/*.class META-INF/*.xml
pause |
8. Triển khai JAAS_Example1.jar bằng cách copy nó vào thư mục %JBOSS_HOME%\server\default\deploy
Ta có kết quả sau trong console JBOSS
10:31:43,505 INFO [ProxyFactory] Bound EJB Home ‘StatelessSession’ to jndi ‘example1/StatelessSession’
10:31:43,515 INFO [ProxyFactory] Bound EJB Home ‘StatefulSession’ to jndi ‘example1/StatefulSession’ 10:31:43,516 INFO [EJBDeployer] Deployed: file:/C:/javaSoft/jboss-4.2.2.GA/server/default/deploy/JAAS_Example1.jar |
9. OK! Mọi thứ của bữa tiệc đã ngon lành. Bắt đầu thưởng thức thôi
C. Tạo client
1. Tạo thư mục client, copy thư mục ejb đã biên dịch ỏ phần trên vào, xóa 2 class : StatefulSessionBean.class và StatelessSessionBean.class.
2. Tạo file SessionClient.java với nội dung sau:
package client;
import java.util.Properties; import javax.naming.Context; import javax.naming.InitialContext; 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.LoginContext; import javax.security.auth.login.LoginException; import ejb.jaas.Session; import ejb.jaas.SessionHome;
public class SessionClient { static class AppCallbackHandler implements CallbackHandler { private String username; private char[] password; public AppCallbackHandler(String username, char[] password) { this.username = username; this.password = password; } public void handle(Callback[] callbacks) throws java.io.IOException, UnsupportedCallbackException { for (int i = 0; i < callbacks.length; i++) { if (callbacks[i] instanceof NameCallback) { NameCallback nc = (NameCallback)callbacks[i]; nc.setName(username); } else if (callbacks[i] instanceof PasswordCallback) { PasswordCallback pc = (PasswordCallback)callbacks[i]; pc.setPassword(password); } else { throw new UnsupportedCallbackException(callbacks[i], “Unrecognized Callback”); } } } } public static void main(String args[]) throws Exception { //chi dinh file config cho client System.setProperty(“java.security.auth.login.config”,”client-auth.conf”); //thiet lap tham so moi truong Properties props = System.getProperties(); props.put( Context.INITIAL_CONTEXT_FACTORY,”org.jnp.interfaces.NamingContextFactory” ); props.put( Context.PROVIDER_URL, “localhost:1099” ); props.put( Context.URL_PKG_PREFIXES, “org.jboss.naming” ); //============================================== String name = “scott”;//đổi sau mỗi lần chạy để thử Char[] password =”echoman”.toCharArray();//… String example = “example1”; System.out.println(“+++ Running SessionClient with username=”+name+”, password=”+ new String(password+)”, example=”+example); try { AppCallbackHandler handler = new AppCallbackHandler(name, password); LoginContext lc = new LoginContext(“TestClient”, handler); System.out.println(“Created LoginContext”); lc.login(); System.out.println(“Login success”); } catch (LoginException le) { System.out.println(“Login failed”); le.printStackTrace(); logger(“client.log”,le.toString()); } try { System.out.println(“Looking for StatelessSession: “+example+”/StatelessSession”); InitialContext iniContext = new InitialContext(); SessionHome home = (SessionHome) iniContext.lookup(example+”/StatelessSession”); System.out.println(“Found StatelessSessionHome”); Session bean = home.create(); System.out.println(“Created StatelessSession”); System.out.println(“Bean.echo(‘Hello’) -> “+bean.echo(“Hello”)); bean.remove(); } catch(Exception e) { e.printStackTrace(); logger(“client.log”,e.toString()); } try { InitialContext iniContext = new InitialContext(); SessionHome home = (SessionHome) iniContext.lookup(example+”/StatefulSession”); System.out.println(“Found StatefulSessionHome”); Session bean = home.create(); System.out.println(“Created StatefulSession”); bean.noop(); System.out.println(“Bean.noop() called”); System.out.println(“Bean.echo(‘Hello’) -> “+bean.echo(“Hello”)); bean.remove(); } catch(Exception e) { e.printStackTrace(); logger(“client.log”,e.toString()); } try { lc.logout(); System.out.println(“–>Logged-out OK.”); } catch (Exception e) { e.printStackTrace(); } } static void logger(String filename,String log ){ try{ java.io.PrintWriter out=new java.io.PrintWriter(new java.io.FileOutputStream(filename)); out.println(“Error: “+new java.util.Date().toString()+”============================”); out.println(log); out.println(“—-ended problem—-“); out.close(); }catch(Exception ex){ ex.printStackTrace(); } } } |
3. Tạo file client-auth.conf trong thư mục client với nội dung
TestClient {
org.jboss.security.ClientLoginModule required; }; |
4. Tạo file app.policy trong thư mục client với nội dung
grant {
permission java.security.AllPermission; }; |
5. Tạo file compile.bat với nội dung sau:
javac -d . *.java
pause |
Chạy file này để biên dịch client. Phải đảm bảo mọi thứ OK.
6. Tạo file client.bat với nội dung sau:
java -Djava.Security.policy=app.policy SessionClient
pause |
7. Đảm bảo CLASSPATH phải cần có đường dẫn đến các files (đã đề cập ở các phần trước) ở thư mục %JBOSS-HOME%\client
8. Chạy file client để thực thi. Kết quả của 1 vài lần chạy như sau
a) Chạy với user = scott, password = echoman, kết quả như sau
+++ Running SessionClient with username=scott, password=echoman, example=example1
Created LoginContext Login success Looking for StatelessSession: example1/StatelessSession Found StatelessSessionHome Created StatelessSession Bean.echo(‘Hello’) -> Hello Found StatefulSessionHome Created StatefulSession Bean.noop() called Bean.echo(‘Hello’) -> Hello –>Logged-out OK. |
b)Chạy với user =scott, password =tambay, kết quả như sau
+++ Running SessionClient with username=scott, password=tambay, example=example1
Created LoginContext Login success Looking for StatelessSession: example1/StatelessSession Found StatelessSessionHome java.rmi.AccessException: SecurityException; nested exception is: javax.security.auth.login.FailedLoginException: Password Incorrect/Password Required … –>Logged-out OK. |
c) Chạy với user=stark, password = javaman, kết quả như sau
+++ Running SessionClient with username=stark, password=javaman, example=example1
Created LoginContext Login success Looking for StatelessSession: example1/StatelessSession Found StatelessSessionHome java.rmi.AccessException: SecurityException; nested exception is: java.lang.SecurityException: Insufficient method permissions, principal=stark, ejbName=StatelessSession, method=create, interface=HOME, requiredRoles=[Echo], principalRoles=[Coder] … –>Logged-out OK. |
Xem thêm các thông báo lỗi ở file client.log.
CHÚC CÁC BẠN THÀNH CÔNG!
Jaychen said
chào a Hải:
Em đã làm tất cả bước trên nhưng đến lúc thực thi phía client thì đến phần lookup thì nó tìm ko thấy, nó bị đứng ngay phần đó (hình dưới):
Mặc dù e đã deploy thành công JAAS_Example1.jar (Hình dưới):
Mong reply của a. Thanks 🙂
Jaychen said
e dùng JBoss 4.2.2.GA. A có thể giải thích những nguyên do vì sao nó lookup ko thấy dùm e đc ko? e search nguyên nhân nhưng vẫn chưa ra 😦
Jaychen said
E tim ra loi rui, do e luc trc e ko bit, e modify cai port de? lookup JNDI, h thi dc rui :).
Thanks a
never said
Thanks a nhieu.