2012-08-31 16 views
9

Tôi đang thử nghiệm tuyên truyền của JAAS Subject với một custom Principal từ một máy khách EJB độc lập đang chạy trên một thời gian chạy Java thô đến một máy chủ JavaEE. Tôi đang nhắm mục tiêu cả triển khai JBoss và WebSphere.Làm thế nào để truyền JAAS Subject khi gọi EJB từ xa (RMI over IIOP) từ một máy khách thuần túy

Theo this forum thread Tôi đã mong đợi nó sẽ hoạt động với JBoss dễ dàng.

Đây là EJB đoạn mã mã khách hàng của tôi:

Subject subject = new Subject(); 
Principal myPrincipal = new MyPrincipal("me I myself"); 
subject.getPrincipals().add(myPrincipal); 

PrivilegedExceptionAction<String> action = new PrivilegedExceptionAction<String>() { 
    public String run() throws Exception { 
      String result; 
      System.out.println("Current Subject: " + Subject.getSubject(AccessController.getContext())); 
      InitialContext ic = new InitialContext(); 
      Business1 b = (Business1) ic.lookup("StatelessBusiness1"); 
      result = b.getNewMessage("Hello World"); 
      return result; 
     } 
    }; 

result = subject.doAs(subject, action); 
System.out.println("result "+result); 

server-side code là:

public String getNewMessage(String msg) { 
    System.out.println("getNewMessage principal: " + sessionContext.getCallerPrincipal()); 
    System.out.println("Current Subject: " + Subject.getSubject(AccessController.getContext())); 
    return "getNewMessage: " + msg; 
} 

Để chắc chắn, ngay cả khi nó là hành vi mặc định, tôi đã thêm phần này vào bean phiên ejb-jar.xml của tôi:

<security-identity> 
    <use-caller-identity/> 
</security-identity> 

Đậu phiên của tôi không được bảo vệ bởi y vai trò.

Theo this IBM WebSphere infocenter section, tôi cũng đã bật thuộc tính hệ thống com.ibm.CSI.rmiOutboundPropagationEnabled=true.

Về mặt kỹ thuật, cuộc gọi dịch vụ hoạt động bình thường trên JBoss hoặc WebSphere. Nhưng Chủ đề JAAS bao gồm hiệu trưởng tùy chỉnh của tôi được tạo trên máy khách không được truyền đến máy chủ. Hoặc tất nhiên, các Subject bán phá giá ngay trước khi tạo bối cảnh JNDI và EJB gọi là OK.

tôi chạy phiên bản Java runtime tương tự cho máy chủ và máy khách (IBM Java6 SR9 FP2 ...), MyPrincipal lớp serializable có sẵn trong máy chủ classpath (AppServer/lib/ext cho WebSphere, server/default/lib cho JBoss)

WebSphere bãi:

[8/31/12 11:56:26:514 CEST] 00000024 SystemOut  O getNewMessage principal: UNAUTHENTICATED 
[8/31/12 11:56:26:515 CEST] 00000024 SystemOut  O Current Subject: null 

JBoss bãi:

12:30:20,540 INFO [STDOUT] getNewMessage principal: anonymous 
12:30:20,540 INFO [STDOUT] Current Subject: null 

Để chắc chắn, tôi đã bỏ lỡ một số loại của ma thuật pell. Bạn có biết cái nào?

+0

Thì sao? Tôi đã viết thành công một LoginModule tùy chỉnh cho hỗ trợ WebSphere và Tivoli PDPrincipal, tôi đã cấu hình LoginModule trong JBoss để kích hoạt Kerberos SPNEGO qua HTTP ... Chắc chắn tôi thấy thoải mái với JAAS và những thứ khác xung quanh. Tôi chỉ hỏi nếu tôi suy nghĩ sai nó nên làm việc ... trước khi mở mã nguồn JBoss để xác minh –

+1

Sau đó, bạn có nhiều kinh nghiệm hơn tôi;) (Tôi đã chơi với LoginModules, xác thực tùy chỉnh, chuyển tiếp chính qua RMI-IIOP/CORBA trong Glassfish 2.x, và điều đó luôn luôn rất phức tạp. Cuối cùng, chúng tôi chỉ xử lý ở cấp độ ứng dụng) Tôi sẽ ngăn cản biểu mẫu bất kỳ bằng cách sử dụng các tiêu chuẩn này để xác thực tên người dùng/mật khẩu. Nếu vấn đề là tích hợp với Kerberos và cung cấp đăng nhập một lần, thì đó vẫn có thể là cách tốt nhất để thực hiện! Xin lỗi, tôi không thể giúp thêm. – ewernli

+0

Nếu thực tế, mục đích là để làm việc xung quanh không sử dụng Kerberos với WebSphere trong bối cảnh cụ thể của chúng tôi: http://stackoverflow.com/questions/10518057/how-to-enable-kerberos-authentication-for-remote-ejb- call-on-websphere –

Trả lời

3

Tôi nghi ngờ bạn chưa bật bảo mật trên máy chủ WS. Vì bảo mật không được kích hoạt và bạn không xác thực với WAS, không có thông tin xác thực. Vì vậy, cuộc gọi của bạn đến getCallerPrincipal đang trở về KHÔNG ĐẢM BẢO.

Nếu bạn bật bảo mật ứng dụng trong WAS, bạn sẽ phải xác thực qua CSIv2 protocol. Tạo chủ đề JAAS của riêng bạn trong một ứng dụng khách độc lập sẽ không làm điều đó. Nếu có thể, thì bất kỳ ai cũng có thể tạo thông tin xác thực "này, đó là tôi" và đăng nhập vào bất kỳ EJB từ xa nào mà họ muốn.

Mã của bạn sẽ hoạt động trên máy chủ bằng cách đính kèm chủ đề của bạn vào chuỗi thực thi đang chạy. Đối tượng chảy/thông tin xác thực trên dây yêu cầu một giao thức để thực hiện tuần tự hóa thông tin chủ đề và đảm bảo sự tin cậy của bên khẳng định danh tính trong thông tin xác thực. Từ một máy khách độc lập, WAS chấp nhận thông tin người dùng dưới dạng ủy quyền cơ bản, LTPA và các kerberos. Điều này có thể được cấu hình trên một cấu hình CSIv2 vào trong bảng điều khiển quản trị. Nó được ghi lại trong liên kết Trung tâm thông tin mà tôi đã tham chiếu trước đó.

Đó là nội dung thú vị. Chúc may mắn.

+0

Cảm ơn và bạn nói đúng, một LoginModule cụ thể là cần thiết cho JBoss. Để tuyên truyền WebSphere không phải là phần dễ nhất, vì vậy tôi quyết định tùy chỉnh chuỗi auth bằng một LoginModule tùy chỉnh và sau đó máy khách JVM phải được cấu hình với sas.client.properties trong com.ibm.CORBA.ConfigURL. Trong mọi trường hợp, các phương thức EJB phải được bảo mật. –

0

có thể điều này sẽ giúp bạn với mức giá sử dụng các lớp websphere độc ​​quyền. như tôi nhớ, WebSphere KHÔNG tuyên truyền JAAS gọi-môn, đây là điển hình để ibm

package foo.bar; 
import java.util.HashMap; 
import java.util.Iterator; 
import java.util.List; 
import java.util.Map; 
import java.util.Set; 
import javax.security.auth.Subject; 
import javax.security.auth.login.CredentialExpiredException; 
import org.apache.log4j.Logger; 
import com.ibm.websphere.security.WSSecurityException; 
import com.ibm.websphere.security.auth.CredentialDestroyedException; 
import com.ibm.websphere.security.auth.WSSubject; 
import com.ibm.websphere.security.cred.WSCredential; 

public class IdentityHelper 
{ 
    private static final Logger log = Logger.getLogger(IdentityHelper.class); 
    private static final String CLASS_OBJECT = "java.util.HashMap"; 
    private static final String KEY_OBJECT = "java.lang.String"; 
    private static final String VALUE_OBJECT = "java.util.HashSet"; 

    private Subject subject=null; 
    private WSCredential creds; 
    private Set publicCredentials=null; 
    public IdentityHelper(Subject _subject) throws WSSecurityException 
    { 
     if(_subject==null) 
     { 
      IdentityHelper.log.warn("given subject was null, using Caller-Subject or the RunAs-Subject!"); 
      this.subject = WSSubject.getCallerSubject(); 
      if(this.subject==null)this.subject=WSSubject.getRunAsSubject(); 
     } 
     else 
     {   
      this.subject=_subject; 
     } 
     init(); 
    } 
    public IdentityHelper() throws WSSecurityException 
    { 
     this.subject=WSSubject.getRunAsSubject(); 
     if(this.subject==null) 
     { 
      IdentityHelper.log.warn("using Caller-Subject NOT the RunAs-Subject!"); 
      this.subject = WSSubject.getCallerSubject(); 
     } 
     init(); 
    } 

    private void init() throws WSSecurityException 
    { 
     Set<WSCredential> credSet= this.subject.getPublicCredentials(WSCredential.class); 
     //set should contain exactly one WSCredential 
     if(credSet.size() > 1) throw new WSSecurityException("Expected one WSCredential, found " + credSet.size()); 
     if(credSet.isEmpty()) 
     { 
      throw new WSSecurityException("Found no credentials"); 
     } 
     Iterator<WSCredential> iter= credSet.iterator(); 
     this.creds=(WSCredential) iter.next(); 
     this.publicCredentials=this.subject.getPublicCredentials(); 
    } 
    public WSCredential getWSCredential() throws WSSecurityException 
    { 
     return this.creds; 
    } 
    public List<String> getGroups() throws WSSecurityException,CredentialDestroyedException,CredentialExpiredException 
    { 
     WSCredential c = this.getWSCredential(); 
     return c.getGroupIds(); 
    } 
    /** 
    * helper method for obtaining user attributes from Subject objects. 
    * @param subject 
    * @return 
    */ 
    @SuppressWarnings("unchecked") 
    public Map<String, Set<String>> getAttributes() 
    { 
     Map<String, Set<String>> attributes = null; 
     Iterator<?> i = this.subject.getPublicCredentials().iterator(); 
     while (attributes == null && i.hasNext()) 
     { 
      Map<String, Set<String>> tmp = null; 
      Object o = i.next(); 
      if(IdentityHelper.log.isDebugEnabled()) 
      { 
       IdentityHelper.log.debug("checking for attributes (class name): " + o.getClass().getName()); 
      } 
      if(!o.getClass().getName().equals(CLASS_OBJECT)) 
       continue;//loop through 
      tmp = (Map) o; 
      Object tObject = null; 
      Iterator<?> t = null; 
      t = tmp.keySet().iterator(); 
      tObject = t.next(); 
      if(IdentityHelper.log.isDebugEnabled()) 
      { 
       IdentityHelper.log.debug("checking for attributes (key object name): " + tObject.getClass().getName()); 
      } 
      if(!tObject.getClass().getName().equals(KEY_OBJECT)) 
       continue;//loop through 
      t = tmp.values().iterator(); 
      tObject = t.next(); 
      if(IdentityHelper.log.isDebugEnabled()) 
      { 
       IdentityHelper.log.debug("checking for attributes (value object name): " + tObject.getClass().getName()); 
      } 
      if(!tObject.getClass().getName().equals(VALUE_OBJECT)) 
       continue;//loop through 
      attributes = (Map) o; 
     } 
     if (attributes == null) 
     { 
      attributes = new HashMap<String, Set<String>>(); 
     } 
     return attributes; 
    } 
    public Subject getSubject() 
    { 
     return this.subject; 
    } 
    protected Set getPublicCredentials() { 
     return publicCredentials; 
    } 


} 

xem thêm: Getting the caller subject from the thread for JAASGetting the RunAs subject from the thread

+0

Tôi đã từ bỏ như xa như bảo mật nên được kích hoạt "toàn cầu" trong Websphere để làm việc, và xác thực Kerberos có thể được yêu cầu để có được SSO mà không yêu cầu người dùng xác thực khi bảo mật được kích hoạt. Là một work-around, tôi đã thiết kế một thực thi ORB PortableInterceptor để gắn thêm các thông điệp IIOP với bối cảnh của riêng tôi, nơi tôi đã lưu tên đăng nhập của người dùng. –

Các vấn đề liên quan