2010-09-30 14 views
9

का उपयोग किए बिना जावा ईई सुरक्षा भूमिकाओं को गतिशील रूप से जोड़ें I ग्लासफ़िश 3.1, बी06 का उपयोग कर जावा ईई 6 एप्लिकेशन विकसित कर रहा हूं। मेरे ऐप को सुरक्षित करने के लिए, मैं एक जेडीबीसीआरम और प्रोग्रामेटिक सुरक्षा का उपयोग कर रहा हूं। यह उपयोगकर्ता नाम और पासवर्ड की जांच करने के लिए ठीक काम करता है। लेकिन जब सुरक्षा भूमिकाओं की घोषणा की बात आती है, तो मुझे एक समस्या है:तैनाती वर्णनकर्ता

जावा ईई 6 में सुरक्षा भूमिकाओं का उपयोग करने के लिए, मुझे उन भूमिकाओं को ईजेबी परिनियोजन वर्णनकर्ता और ग्लासफ़िश-विशिष्ट परिनियोजन वर्णनकर्ता में उन भूमिकाओं को घोषित करना होगा भूमिकाएं (जैसा कि Java EE 6-tutorial में बताया गया है) अनुमतियों की जांच के लिए मैं ईजेबी के अंदर विधि isCallerInRole (स्ट्रिंग रोलरफ) का उपयोग कर सकता हूं।

यह मेरे आवेदन के लिए वांछनीय नहीं है, क्योंकि मैं चाहता हूं कि एक्सएमएल फाइलों को लिखने के बिना गतिशील और प्रोग्रामेटिक रूप से सुरक्षा भूमिकाएं जोड़ना संभव हो (और उदाहरण के लिए डेटाबेस में भूमिका नाम परिभाषित करना संभव हो)।

मैंने अभी जीएफ 3-स्रोत कोड के माध्यम से डीबग किया है और com.sun.ejb.containers.EjbContextImpl में IsCallerInRole के कार्यान्वयन को देखा है। वहाँ कंटेनर EJB वर्णनकर्ता से बाहर हो जाता है भूमिकाओं:

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

मैं चारों ओर देखा और अगर मैं किसी भी तरह अपने आवेदन के अंदर EJB वर्णनकर्ता मिल सकता है, मैं इस तरह की एक भूमिका जोड़ सकता है कि पता चला:

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); 

किसी ने ऐसा कुछ किया है, या इसके बारे में कुछ विचार हैं? क्या मेरे आवेदन के अंदर ईजेबी परिनियोजन वर्णनकर्ता का उपयोग करना संभव है? या क्या बेहतर दृष्टिकोण हैं?

पीएस या क्या मुझे भूमिका जोड़ने के लिए एमबीन का उपयोग करना चाहिए? here से काफी संबंधित पोस्ट मिला।

/** 
    * 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); 

हालांकि, मैंने पाया है कि कम से कम JBoss के साथ के रूप में यह पहले से उन भूमिकाओं घोषित करने के लिए सभी को एक आवश्यक नहीं है:

+1

एक तरफ के रूप में, मैं आपको ग्लासफ़िश सर्वर 3.1 के हाल के निर्माण के लिए आगे बढ़ने के लिए प्रोत्साहित करता हूं। टीम ने हाल ही में रिलीज 22. – vkraemer

+0

धन्यवाद जारी किया। दुर्भाग्यवश, हमारे पास कुछ पुस्तकालय हैं जो उच्च ग्लासफ़िश संस्करणों को तोड़ते हैं, इसलिए हमें 06 के साथ रहना होगा जब तक कि इन libs में कई बग ठीक नहीं हैं – ifischer

उत्तर

3

जावाडोक इस आवश्यकता को स्पष्ट रूप से उल्लेख है। हमारे मामले में, मूल भूमिकाएं सिस्टम में गतिशील रूप से बनाई जाती हैं और प्रमाणीकरण होने पर असाइन की जाती हैं। यह उन लोगों को घोषित करना असंभव है।

फिर भी, isCallerInRole विधि पूरी तरह से अच्छी तरह से काम करता है।

मुझे एहसास है कि जेबॉस एएस में स्विचिंग एक समाधान नहीं है, लेकिन शायद यह जानकारी किसी के लिए मूल्यवान है।

3

मैं प्रोग्राम के रूप में प्रवेश के बाद भूमिकाओं को जोड़ने के लिए निम्नलिखित समाधान है, जो कम से कम ग्लासफिश 3.1.2 निर्माण पर काम करता है के साथ आया था 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); 
    } 
} 

आप अपने प्रोजेक्ट को security.jar और common-util.jar ग्लासफिश से जोड़ने की आवश्यकता होगी पुस्तकालयों।

और अपनी वेब.एक्सएमएल में <security-role> अनुभाग बनाने के लिए मत भूलना जो आप जोड़ना चाहते हैं।

ध्यान दें कि मैं कार्यक्षमता का उपयोग कर रहा हूं जो एक प्रकाशित स्थिर एपीआई का हिस्सा नहीं दिखता है, इसलिए इस बात की कोई गारंटी नहीं है कि यह ग्लासफ़िश की भावी रिलीज में काम करेगा।

मुझे ग्लासफ़िश के sun.appserv.security.AppservPasswordLoginModule.commit() के स्रोत कोड से भूमिका जोड़ने के तरीके के बारे में जानकारी मिली। यदि भविष्य में ग्लासफ़िश रिलीज मेरा कोड तोड़ता है, तो यह फ़ंक्शन इसे ठीक करने के तरीके को जानने के लिए शुरू करने के लिए एक अच्छी जगह होगी।

+2

समस्या के एक हिस्से के लिए अच्छा समाधान। हालांकि, मुझे अभी भी web.xml के अंदर स्थाई भूमिकाओं को परिभाषित करना है। लेकिन मैं सर्वर को पुनरारंभ किए बिना गतिशील रूप से भूमिकाएं जोड़ना चाहता हूं। हम इसे एक अलग तरीके से समाप्त कर दिया। विस्तार से याद नहीं किया जा सकता है, लेकिन मुझे लगता है कि हमने ग्लासफ़िश सुरक्षा तंत्र के एक बड़े हिस्से को अपने साथ बदल दिया है। – ifischer

+3

मैं ifischer से सहमत हूं। एकमात्र वास्तविक समाधान को कुछ भी स्थिर रूप से जोड़ने की ज़रूरत नहीं है। यह वास्तव में spec में जोड़ा जाना चाहिए। मजबूर घोषणा एक बार एक अच्छा विचार प्रतीत हो सकती है, लेकिन व्यावहारिक रूप से यह गंभीर रूप से सीमित है और विशेष रूप से ग्लासफ़िश में सुस्त वर्बोज़ में। –

संबंधित मुद्दे