2010-09-30 25 views
9

Tôi đang phát triển một ứng dụng Java EE 6 bằng Glassfish 3.1, B06. Để bảo mật ứng dụng của tôi, tôi đang sử dụng bảo mật JDBCRealm và chương trình. Điều này hoạt động tốt để kiểm tra tên người dùng và mật khẩu. Nhưng khi nói đến tuyên bố vai trò bảo mật, tôi có vấn đề:Tự động thêm vai trò bảo mật Java EE mà không sử dụng mô tả triển khai

Để sử dụng Vai trò bảo mật trong Java EE 6, tôi phải khai báo vai trò đó trong bộ mô tả triển khai EJB và trong mô tả triển khai Glassfish cụ thể để liên kết vai trò (như được giải thích trong các Java EE 6-tutorial) Chỉ hơn tôi có thể sử dụng phương pháp isCallerInRole (String roleRef) bên trong EJB để kiểm tra quyền. Điều này là không mong muốn cho ứng dụng của tôi, vì tôi muốn có thể thêm vai trò bảo mật cả động và lập trình, mà không cần phải viết các tệp XML (và ví dụ như có thể xác định tên vai trò trong cơ sở dữ liệu).

Tôi vừa sửa lỗi thông qua mã nguồn GF3 và thấy việc triển khai isCallerInRole trong com.sun.ejb.containers.EjbContextImpl. Có container được vai trò ra khỏi mô tả EJB:

public boolean isCallerInRole(String roleRef) { 
    (...) 
    EjbDescriptor ejbd = container.getEjbDescriptor(); 
    RoleReference rr = ejbd.getRoleReferenceByName(roleRef); 
    (...) 
} 

Tôi nhìn quanh và phát hiện ra rằng nếu tôi bằng cách nào đó có thể nhận được các mô tả EJB bên trong ứng dụng của tôi, tôi có thể thêm một vai trò như thế này:

EjbDescriptor ejbd = //??? Can i use that descriptor inside my app, or is that "forbidden"? 
RoleReference rr = new RoleReference("admin", "Admins are allowed to do everything"); 
ejbd.addRoleReference(rr); 

Bất cứ ai đã làm điều gì đó như thế này, hoặc có một số suy nghĩ về nó? Có thể sử dụng bộ mô tả triển khai Ejb bên trong ứng dụng của tôi không? Hoặc có cách tiếp cận tốt hơn?

P.S. hoặc tôi nên sử dụng MBeans để thêm Vai trò? Đã tìm thấy một bài đăng khá liên quan here.

+1

Ngoài ra, tôi khuyến khích bạn chuyển sang phiên bản mới hơn của GlassFish Server 3.1. Nhóm gần đây đã phát hành phiên bản 22. – vkraemer

+0

Cảm ơn bạn. Thật không may, chúng tôi có một số thư viện mà phá vỡ ở phiên bản cao hơn Glassfish, vì vậy chúng tôi phải gắn bó với 06 cho đến khi một số lỗi trong các libs được cố định – ifischer

Trả lời

3

Các Javadoc không đề cập đến yêu cầu này một cách rõ ràng:

/** 
    * Tests if the caller has a given role. 
    * 
    * @param roleName - The name of the security role. The role must be one of the security roles that 
    * is defined in the deployment descriptor. 
    * @return True if the caller has the specified role. 
    */ 
    public boolean isCallerInRole(String roleName); 

Tuy nhiên, tôi thấy rằng ít nhất là với JBoss AS nó không cần thiết ở tất cả các tuyên bố những vai trò trước. Trong trường hợp của chúng tôi, các vai trò chính được tạo động trong hệ thống và được chỉ định khi xác thực diễn ra. Do đó, không thể tuyên bố những người trả trước.

Tuy nhiên, phương thức isCallerInRole hoạt động hoàn toàn tốt.

Tôi nhận thấy việc chuyển sang JBoss AS không phải là giải pháp, nhưng có thể thông tin này có giá trị đối với người khác.

3

tôi đã đưa ra các giải pháp sau đây để thêm vai trò lập trình sau khi đăng nhập, hoạt động ít nhất là trên GlassFish 3.1.2 build 23.

import com.sun.enterprise.security.SecurityContext; 
import com.sun.enterprise.security.web.integration.PrincipalGroupFactory; 
import java.security.Principal; 
import java.util.Set; 
import javax.security.auth.Subject; 
import org.glassfish.security.common.Group; 

public class GlassFishUtils { 
    public static void addGroupToCurrentUser(String groupName, String realmName) { 
     Subject subject = SecurityContext.getCurrent().getSubject(); 
     Set<Principal> principals = subject.getPrincipals(); 
     Group group = PrincipalGroupFactory.getGroupInstance(groupName, realmName); 
     if (!principals.contains(group)) 
      principals.add(group); 
    } 
} 

Bạn sẽ cần phải thêm security.jarcommon-util.jar từ GlassFish để dự án của bạn thư viện.

Và đừng quên tạo phần <security-role> trong tệp web.xml của bạn cho các vai trò bạn muốn thêm.

Lưu ý rằng tôi đang sử dụng chức năng không phải là một phần của API ổn định đã xuất bản, vì vậy không đảm bảo rằng điều này sẽ tiếp tục hoạt động trong các bản phát hành GlassFish trong tương lai.

Tôi đã nhận thông tin về cách thêm vai trò từ mã nguồn của sun.appserv.security.AppservPasswordLoginModule.commit() của GlassFish. Nếu bản phát hành GlassFish trong tương lai vi phạm mã của tôi, chức năng này sẽ là một nơi tốt để bắt đầu để tìm hiểu cách khắc phục.

+2

Giải pháp tốt cho một phần của vấn đề. Tuy nhiên, tôi vẫn phải xác định các vai trò tĩnh bên trong web.xml. Nhưng tôi muốn thêm các vai trò động mà không phải khởi động lại Máy chủ. Chúng tôi đã làm nó theo một cách khác. Không thể nhớ chi tiết, nhưng tôi nghĩ chúng tôi đã thay thế một phần lớn cơ chế bảo mật Glassfish bằng chính cơ chế của mình. – ifischer

+3

Tôi đồng ý với ifischer. Giải pháp thực sự duy nhất không phải thêm bất kỳ thứ gì tĩnh. Điều này nên được thêm vào spec thực sự. Việc tuyên bố cưỡng bức có vẻ như là một ý tưởng tốt một lần, nhưng trong thực tế nó bị hạn chế nghiêm trọng và đặc biệt là trong Glassfish. –

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