核心組件
1. 遠程介面 Calculator
@Remote
public interface Calculator {
int add(int x, int y);
int subtract(int x, int y);
int divide(int x, int y);
}
2. Bean 實作 CalculatorBean
@Stateless
@SecurityDomain("other")
public class CalculatorBean implements Calculator {
@Unchecked
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public int add(int x, int y) { return x + y; }
@MethodPermissions({"student","teacher"})
public int subtract(int x, int y) { return x - y; }
@MethodPermissions({"teacher"})
public int divide(int x, int y) { return x / y; }
}
@SecurityDomain("other") 指向 JBoss 安全域(對應 login-config.xml 中的 <application-policy name="other">)。
@Unchecked 允許匿名訪問 add。
@MethodPermissions 宣告角色授權:subtract 學生/教師可用,divide 僅教師。
3. 客戶端驗證 Client.java
InitialContext ctx = new InitialContext();
Calculator calc = (Calculator) ctx.lookup(Calculator.class.getName());
// 所有人可加法
System.out.println("1+1=" + calc.add(1,1));
// 切換為 student: kabir/validpassWord
SecurityAssociation.setPrincipal(new SimplePrincipal("kabir"));
SecurityAssociation.setCredential("validpassWord".toCharArray());
System.out.println("1-1=" + calc.subtract(1,1));
try { calc.divide(16,4); } catch (SecurityException e) { /* 拒絕 */ }
// 切換為 teacher: roson/sandy
SecurityAssociation.setPrincipal(new SimplePrincipal("roson"));
SecurityAssociation.setCredential("sandy".toCharArray());
System.out.println("16/4=" + calc.divide(16,4)); // 成功
4. 安全域配置文件
users.properties:kabir=validpassWord、roson=sandy(用戶=密碼)。
roles.properties:kabir=student、roson=teacher(用戶=角色,多角色逗號分隔)。
5. log4j.properties(避免缺 Appender 警告)
log4j.rootLogger=stdout,R
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) -%m%n
log4j.appender.R=org.apache.log4j.RollingFileAppender
log4j.appender.R.File=record.log
log4j.appender.R.MaxFileSize=100KB
log4j.appender.R.MaxBackupIndex=1
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%p %d{hh:mm:ss} %t %c{1} -%m%n
部署與運行
- JBoss 啟動:
run.bat -c all(Windows)。
- Ant 構建:
ant build → ant run。
關鍵點總結
- EJB 3.0 用 Annotation 替代 XML 部署描述符,權限控制直觀清晰。
SecurityAssociation 為線程綁定 Principal/Credential,實現客戶端身份傳播。
- 安全域配置外置,便於整合 LDAP/Database 等實際用戶存儲。