2009-05-26 22 views
41

क्या जर्सी में प्रोग्राम प्रबंधन या सुरक्षा प्रोग्रामिंग प्राप्त करने का कोई तरीका है, उदा। वेब अनुप्रयोग सत्र प्रबंधन? या लेनदेन, सत्र और सुरक्षा सभी कंटेनर द्वारा संभाली जाती है जिसमें जर्सी आवेदन तैनात किया जाता है?जर्सी सुरक्षा और सत्र प्रबंधन

+0

मैंने अभी भी इसकी जांच शुरू कर दी है। अगर मुझे कुछ भी मिल जाए तो मैं जवाब दूंगा –

उत्तर

68

सत्र प्रबंधन कंटेनर का दायरा है जिसमें जर्सी तैनात किया गया है। अधिकांश उत्पादन मामलों में, इसे एक कंटेनर के भीतर तैनात किया जाएगा जो सत्र प्रबंधन करता है।

नीचे कोड एक जर्सी संसाधन उस सत्र में सत्र वस्तु और दुकानों मूल्यों हो जाता है और बाद में कॉल पर उन्हें पुन: प्राप्त करता का एक सरल उदाहरण है।

@Path("/helloworld") 
public class HelloWorld { 

    @GET 
    @Produces("text/plain") 
    public String hello(@Context HttpServletRequest req) { 

     HttpSession session= req.getSession(true); 
     Object foo = session.getAttribute("foo"); 
     if (foo!=null) { 
      System.out.println(foo.toString()); 
     } else { 
      foo = "bar"; 
      session.setAttribute("foo", "bar"); 
     } 
     return foo.toString(); 


    } 
} 
+0

धन्यवाद जैक, मुझे इसकी आवश्यकता है क्योंकि हमें जेएक्स-आरएस वेब सेवाओं पर कुछ प्रकार के एक्सेस कंट्रोल को लागू करना होगा .. उस पर किसी भी मदद की भी सराहना की जाएगी .. अग्रिम धन्यवाद , अधीर – Adhir

+0

@ जैक कॉक्स: मैंने यहां एक संबंधित प्रश्न पोस्ट किया है: http://stackoverflow.com/questions/9676588/how-can-you-authenticate-using-the-jersey-client-against-a-jaas- सक्षम-वेब-सर्व शायद आपको पता चलेगा कि क्लाइंट साइड (जर्सी-क्लाइंट के साथ) पर यह कैसे करें? – carlspring

+0

@ जैक कॉक्स, अगर मेरे पास एक ही समय में 1000 उपयोगकर्ताओं के साथ एक आवेदक है और प्रत्येक सेट 'session.setAttribute (" उपयोगकर्ता नाम ", उपयोगकर्ता नाम)'। क्या जावा समझता है कि 1000 अलग-अलग सत्र होते हैं जिनमें प्रत्येक उपयोगकर्ता नाम से भिन्नता वाले 'उपयोगकर्ता नाम' नामक चर होता है? – kasavbere

6

सत्रों के बारे में जैक की प्रतिक्रिया सही है। वे उस कंटेनर के लिए विशिष्ट हैं जो आप निष्पादित करते हैं, हालांकि सर्वलेट स्पेक कम से कम आपको जावाईई कंटेनर के बीच पोर्टेबिलिटी देता है।

सुरक्षा के लिए, कम से कम आपको जावा (जावा प्रमाणीकरण और प्राधिकरण सेवा) और servlet filter पर नियोजित करके इसे अपने जेएक्स-आरएस विशिष्ट कोड से अलग करने का अवसर मिला है। फिल्टर का उपयोग HTTP प्रमाणीकरण को लागू करने के लिए किया जा सकता है और, सफल लेख पर, उचित प्रिंसिपल के साथ जास विषय सेट करें। आपके जेएक्स-आरएस संसाधन विषय पर उचित प्रिंसिपल की जांच कर सकते हैं। चूंकि आप पूरे ढेर को नियंत्रित करते हैं, इसलिए आप अपने संसाधनों में एक प्रमाणीकृत उपयोगकर्ता पर भरोसा कर सकते हैं (लेकिन इसका परीक्षण करें!), और आप संसाधन कोड में मौजूदा ऑपरेशन के आधार पर प्राधिकरण को लागू कर सकते हैं।

+1

+1 एक अच्छा विचार की तरह लगता है। ग्रिज़ली पर काम करने के लिए आप इसे कैसे प्राप्त कर सकते हैं? मैंने एक नया सवाल खोला। http://stackoverflow.com/questions/1682061/using-jaas-with-jersey-on-grizzly – User1

3

जर्सी सुरक्षा के लिए आपको जर्सी ओएथ समर्थन पर एक नज़र डालना चाहिए। ओएथ पूरी तरह से फिट बैठता है जब आप अपने सिस्टम के लिए बाहरी उपयोगकर्ताओं को एपीआई का पर्दाफाश करते हैं। लिंक्डइन एपीआई

http://wikis.oracle.com/display/Jersey/OAuth

+0

कृपया – bekce

23

की तरह उदाहरण के लिए मैंने सोचा था कि सत्र कुछ है हम चाहिए कभी नहीं RESTful अनुप्रयोगों में उपयोग ...

Yegor सही है। हमें सर्वर पक्ष ला ला पारंपरिक वेब एप्लिकेशन में कभी भी राज्य को बनाए रखना नहीं चाहिए। यदि आप एक decoupled SOA- उन्मुख अनुप्रयोग बनाना चाहते हैं तो आपको आरईएसटी वेब सेवाओं के लिए किसी एपीआई/फ्रेमवर्क का उपयोग करने की आवश्यकता नहीं है। यदि आपको सर्वर क्लाइंट में वैश्विक क्लाइंट-सर्वर स्थिति को बनाए रखने की आवश्यकता है, या चाहते हैं, तो आप निश्चित रूप से निर्माण कर रहे हैं जिसे हम एसओए-उन्मुख [वेब] ऐप के रूप में वर्णित कर सकते हैं, लेकिन जर्सी का उपयोग [वेब] विकास ढांचे की तरह करते हैं। अनजाने में आप एक वेब सेवा (आरईएसटी या अन्यथा) की प्रकृति को घुमा रहे हैं। आप इसे पहले उत्तर में सुझाए गए तरीके से कर सकते हैं, लेकिन आप नहीं होना चाहिए। अंतिम परिणाम वेब सेवा नहीं है, केवल वेब सेवाओं के टूल के साथ बनाया गया एक नियमित ऐप है।

@GET 
@PRODUCES(MediaType.APPLICATION_JSON) 
public String returnClients(@Context HTTPServletRequest request(
    String auth = request.getHeader("Authorization"); 
    Account acc = null; 
    if (auth!=null) { 
     Account acc = Utils.LoginAccount(auth); 
    } 
    if (acc == null) 
    // not logged in, handle it gracefully 

इस तरह एक सत्र प्रारंभ किए बिना प्रमाणीकरण है:

+2

लिंक को ठीक करें यह हमेशा सत्य नहीं है। यदि सत्र को कैशिंग प्रतिक्रियाओं के साधन के रूप में उपयोग किया जाता है तो कोई तर्क दे सकता है कि इसका प्रदर्शन प्रदर्शन में सुधार करने के लिए किया जाता है। आप अभी भी कैशिंग तंत्र के रूप में सत्र के साथ एक स्टेटलेस एप्लिकेशन लिख सकते हैं। – Vladimir

+0

वेबपैस चलाने के लिए webservices के शीर्ष पर फेसबुक उपयोग सत्र जैसी वेबसाइटें। यह स्वाभाविक रूप से गलत नहीं है। आप शायद एक उपयोगकर्ता को एक webservice का उपयोग करने के लिए प्रमाणित करना चाहें, जिस स्थिति में आप हर बार क्रेडेंशियल्स पास नहीं करना चाहते हैं। – DiamondDrake

4

-_o मैं ग्राहकों प्राधिकरण शीर्ष लेख होने और इस तरह बाकी methode में यह परीक्षण इस समस्या का समाधान।

+1

एनबी: यह पूरी तरह से असुरक्षित है जब तक कि आप HTTPS कनेक्शन को मजबूर नहीं कर रहे हैं, इस स्थिति में आप ड्रॉपविज़ार्ड-एथ का भी उपयोग कर सकते हैं। – Lambart

15

हाँ यह संभव है।जर्सी documentation का कहना है:

सुरक्षा के लिए एक अनुरोध के बारे में जानकारी @Context एनोटेशन का उपयोग कर एक JAX-आरएस SecurityContext उदाहरण इंजेक्शन लगाने के द्वारा उपलब्ध है। इंजेक्शन सुरक्षा संदर्भ उदाहरण HttpServletRequest API पर उपलब्ध कार्यक्षमता के बराबर प्रदान करता है। इंजेक्शन सुरक्षा संदर्भ वास्तविक जर्सी अनुप्रयोग परिनियोजन पर निर्भर करता है। उदाहरण के लिए, के लिए एक सर्वलेट कंटेनर में तैनात जर्सी अनुप्रयोग के लिए, जर्सी सुरक्षा कॉन्टेक्स्ट एक सुरक्षा संदर्भ से सर्वलेट अनुरोध से पुनर्प्राप्त जानकारी से जानकारी को समाहित करेगा। एक ग्रिज़ली सर्वर पर तैनात जर्सी एप्लिकेशन के मामले में, सुरक्षा कॉन्टेक्स्ट ग्रिज़ली अनुरोध से पुनर्प्राप्त जानकारी लौटाएगा।

उदाहरण:

@Path("basket") 
public ShoppingBasketResource get(@Context SecurityContext sc) { 
    if (sc.isUserInRole("PreferredCustomer") { 
     return new PreferredCustomerShoppingBasketResource(); 
    } else { 
     return new ShoppingBasketResource(); 
    } 
} 

या

@Path("resource") 
@Singleton 
public static class MyResource { 
    // Jersey will inject proxy of Security Context 
    @Context 
    SecurityContext securityContext; 

    @GET 
    public String getUserPrincipal() { 
     return securityContext.getUserPrincipal().getName(); 
    } 
} 

या यदि आप एनोटेशन के साथ बॉक्स से बाहर सुरक्षा चाहते हैं जाँच these docs

जर्सी भी आप SecurityContext अनुकूलित करने के लिए अनुमति देता है:

SecurityContext सीधे ContainerRequestContext से प्राप्त किए जा सकें getSecurityContext के माध्यम से() विधि। आप सेट सिक्योरिटी कॉन्टेक्स्ट (सुरक्षा कॉन्टेक्स्ट) विधि का उपयोग कर एक कस्टम एक अनुरोध संदर्भ में डिफ़ॉल्ट सुरक्षा कॉन्टेक्स्ट को प्रतिस्थापित कर सकते हैं। यदि आप अपने कंटेनररक्वेटफिल्टर में कस्टम सुरक्षा कॉन्टेक्स्ट उदाहरण सेट करते हैं, तो यह सुरक्षा संदर्भ उदाहरण JAX-RS संसाधन वर्ग फ़ील्ड में इंजेक्शन के लिए उपयोग किया जाएगा। इस तरह आप कस्टम प्रमाणीकरण फ़िल्टर को कार्यान्वित कर सकते हैं जो आपके स्वयं के सुरक्षा कॉन्टेक्स्ट को उपयोग करने के लिए सेट कर सकता है। अपने कस्टम प्रमाणीकरण अनुरोध फ़िल्टर के प्रारंभिक निष्पादन को सुनिश्चित करने के लिए, प्राथमिकताओं से स्थिरांक का उपयोग करके प्रमाणीकरण को फ़िल्टर प्राथमिकता सेट करें। प्रमाणीकरण फ़िल्टर का प्रारंभिक निष्पादन यह सुनिश्चित करेगा कि अन्य सभी फ़िल्टर, संसाधन, संसाधन विधियां और उप-संसाधन लोकेटर आपके कस्टम सुरक्षा कॉन्टेक्स्ट उदाहरण के साथ निष्पादित होंगे।

examples on how to use request filters with Jersey देखें। और मेरा निम्नलिखित उदाहरण देखें:

import javax.annotation.Priority; 
import javax.ws.rs.Priorities; 

@Provider 
@Priority(Priorities.AUTHENTICATION) 
public class AuthRequestFilter implements ContainerRequestFilter { 
    @Context 
    HttpServletRequest webRequest; 

    @Override 
    public void filter(ContainerRequestContext requestContext) throws IOException { 
     final HttpSession session = webRequest.getSession(); 

     requestContext.setSecurityContext(new SecurityContext() { 
      @Override 
      public Principal getUserPrincipal() { 
       return new PrincipalImpl((String)session.getAttribute("USER_NAME")); 
      } 

      @Override 
      public boolean isUserInRole(String s) { 
       return false; 
      } 

      @Override 
      public boolean isSecure() { 
       return false; 
      } 

      @Override 
      public String getAuthenticationScheme() { 
       return null; 
      } 
     }); 
    } 
} 

चेतावनी! This was introduced in Jersey 2.4। ग्लासफ़िश 4.0.0 पुराने जर्सी 2.0 का उपयोग करता है इसलिए आपको upgrade Jersey using these tips (यह अच्छी तरह से काम करने के लिए साबित नहीं हुआ) होगा। या बेहतर तरीका the nightly build of Glassfish 4.0.1 डाउनलोड करना है। लेकिन यह इस समय पूरी तरह से स्थिर नहीं है। मुझे उम्मीद है कि नया संस्करण जल्द ही जारी किया जाएगा।

अद्यतन: फिलहाल (2014-02-14) Glassfish 4.0.1 रात निर्माण जर्सी 2.5.1 का उपयोग करता है और संदर्भ इंजेक्शन महान काम करता है।

+1

महान जवाब! धन्यवाद –

2

आप उपयोगकर्ता नाम को एक नाम के तहत सेवाओं को समूहित करने के लिए @path कर सकते हैं। उदाहरण।

@Path("/helloworld") 
public class HelloWorld { 

    @GET 
    @Produces("text/plain") 
    public String hello() { 


     return ""; 


    } 
}
Instead of @Path("/helloworld") use 
@Path("admin/helloworld") to expose you class as rest and bind filter on "admin/" 
in web.xml as below. 

<servlet> 
      <servlet-name>jersey-serlvet</servlet-name> 
      <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class> 
      <init-param> 
       <param-name>com.sun.jersey.config.property.packages</param-name> 
       <param-value>/</param-value> 
      </init-param> 
      <load-on-startup>1</load-on-startup> 
     </servlet> 
     <servlet-mapping> 
      <servlet-name>jersey-serlvet</servlet-name> 
      <url-pattern>/rest/*</url-pattern> 
     </servlet-mapping> 
     <filter> 
      <filter-name>myfilter</filter-name> 
      <filter-class>com.Filterclass</filter-class> 
     </filter> 
     <filter-mapping> 
      <filter-name>myfilter</filter-name> 
      <url-pattern>/rest/admin/*</url-pattern> 
     </filter-mapping> 

    public class Filterclass implements Filter { 
     public void doFilter(ServletRequest request, ServletResponse response, 
       FilterChain chain) 
       throws IOException, ServletException { 
        try{ 
         chain.doFilter(request, response); 
        }catch(Exception e){ 
        e.printStackTrace(); 
         } 
      } 
    }

आप इस फिल्टर कक्षा में सत्र सत्यापित कर सकें।

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