2010-02-07 12 views
7

के साथ ठीक-ठीक प्रमाणीकरण मैं एक अच्छी तरह से प्रमाणित प्रमाणीकरण के साथ रीस्टलेट का उपयोग करके संसाधन का खुलासा करना चाहता हूं। मेरा ServerResource केवल GET के माध्यम से प्रमाणीकृत सदस्यों (बेसिक प्रमाणीकरण का उपयोग करके) के माध्यम से पहुंच योग्य होना चाहिए। हालांकि, POST का उपयोग करने के अनुरोध किसी भी प्रमाणीकरण के बिना कॉलर्स के लिए भी उपलब्ध होना चाहिए।रीस्टलेट

आदेश clearify करने के लिए: http://path/myapp/user किसी POST का उपयोग कर रजिस्टर करने के लिए अनुमति चाहिए, लेकिन केवल पंजीकृत सदस्यों GET करने के लिए सभी उपयोगकर्ताओं की सूची में सक्षम होना चाहिए।

दुर्भाग्यवश मैं रीस्टलेट में ज्यादा नहीं हूं और मुझे केवल Restlet एस या Router एस के लिए कोरसर प्रमाणीकरण का उपयोग करने वाले उदाहरण मिलते हैं।

तो मैं संसाधनों के लिए वैकल्पिक प्रमाणीकरण कैसे सक्षम करूं और उन्हें प्रति-विधि स्तर पर जांचूं?

अग्रिम धन्यवाद!

उत्तर

15

रीस्टलेट 2.0 में मूल प्रमाणीकरण करने के लिए (मुझे लगता है कि आप 2.012 का उपयोग कर रहे हैं क्योंकि आप ServerResource का उल्लेख करते हैं), आपको ChallengeAuthenticator का उपयोग करने की आवश्यकता है। यदि यह optional = true के साथ कॉन्फ़िगर किया गया है तो प्रमाणीकरण केवल तभी अनुरोध किया जाएगा यदि आप ChallengeAuthenticator.challenge() का आह्वान करते हैं।

आप एक authenticate() विधि के साथ अपने आवेदन बना सकते हैं, और इस फोन जब भी आप सुरक्षित किया जा करने के लिए एक संसाधन के लिए उपयोग की जरूरत है:

आवेदन:

package example; 

import org.restlet.*; 
import org.restlet.data.ChallengeScheme; 
import org.restlet.routing.Router; 
import org.restlet.security.*; 

public class ExampleApp extends Application { 

    private ChallengeAuthenticator authenticatior; 

    private ChallengeAuthenticator createAuthenticator() { 
     Context context = getContext(); 
     boolean optional = true; 
     ChallengeScheme challengeScheme = ChallengeScheme.HTTP_BASIC; 
     String realm = "Example site"; 

     // MapVerifier isn't very secure; see docs for alternatives 
     MapVerifier verifier = new MapVerifier(); 
     verifier.getLocalSecrets().put("user", "password".toCharArray()); 

     ChallengeAuthenticator auth = new ChallengeAuthenticator(context, optional, challengeScheme, realm, verifier) { 
      @Override 
      protected boolean authenticate(Request request, Response response) { 
       if (request.getChallengeResponse() == null) { 
        return false; 
       } else { 
        return super.authenticate(request, response); 
       } 
      } 
     }; 

     return auth; 
    } 

    @Override 
    public Restlet createInboundRoot() { 
     this.authenticatior = createAuthenticator(); 

     Router router = new Router(); 
     router.attach("/user", UserResource.class); 

     authenticatior.setNext(router); 
     return authenticatior; 
    } 

    public boolean authenticate(Request request, Response response) { 
     if (!request.getClientInfo().isAuthenticated()) { 
      authenticatior.challenge(response, false); 
      return false; 
     } 
     return true; 
    } 

} 

संसाधन:

package example; 

import org.restlet.data.MediaType; 
import org.restlet.representation.EmptyRepresentation; 
import org.restlet.representation.Representation; 
import org.restlet.representation.StringRepresentation; 
import org.restlet.resource.ServerResource; 

public class UserResource extends ServerResource { 

    @Override 
    public Representation get() { 
     ExampleApp app = (ExampleApp) getApplication(); 
     if (!app.authenticate(getRequest(), getResponse())) { 
      // Not authenticated 
      return new EmptyRepresentation(); 
     } 

     // Generate list of users 
     // ... 
    }  

    @Override 
    public Representation post(Representation entity) { 
     // Handle post 
     // ... 
    } 

} 
+0

आपके उत्तर के लिए सबसे पहले धन्यवाद, यह आशाजनक लग रहा है। हालांकि, मुझे आपके कोड को काम करने में कुछ समस्याएं हैं। उदाहरण के लिए, क्लाइंटइन्फो के लिए कोई 'getSubject() 'विधि नहीं है (मैं 2.0m7 का उपयोग कर रहा हूं)। साथ ही, मुझे यकीन नहीं है कि आपकी 'प्रमाणीकृत()' विधि सही है या नहीं? –

+0

मैं पहले स्नैपशॉट का उपयोग कर रहा था; मैंने 2.0m7 के साथ काम करने के लिए उदाहरण अपडेट किए हैं। – Sam

+0

धन्यवाद, फिर, अब कोड संकलित और POST हमेशा उपलब्ध है। दुर्भाग्य से, कभी नहीं मिलता है। कोई फर्क नहीं पड़ता कि मैं कोई गलत, गलत या सही मूलभूत प्रमाण-पत्र प्रदान करता हूं, मुझे हमेशा 401 मिलते हैं। –

5

मैं वर्तमान में Restlet v2.0.10 का उपयोग कर रहा हूँ।

ChallengeAuthenticator.isOptional() के साथ समस्या यह है कि यह सब कुछ या कुछ भी नहीं है। ऊपर @ समुद्र 36 द्वारा प्रदान किए गए उत्तर का एक विकल्प ChallengeAuthenticator.beforeHandle() को प्रमाणीकरण करने या अनुरोध विधि के आधार पर इसे छोड़ने के लिए ओवरराइड करना है। उदाहरण के लिए, नीचे दिया गया संसाधन केवल जीईटी विधि का उपयोग होने पर प्रमाणीकरण की आवश्यकता होगी।

आवेदन:

package example; 

import org.restlet.*; 
import org.restlet.data.ChallengeScheme; 
import org.restlet.routing.Router; 
import org.restlet.security.ChallengeAuthenticator; 
import org.restlet.security.MapVerifier; 

public class ExampleApp extends Application { 

    private ChallengeAuthenticator createAuthenticator() { 
     Context context = getContext(); 
     ChallengeScheme challengeScheme = ChallengeScheme.HTTP_BASIC; 
     String realm = "Example site"; 

     // MapVerifier isn't very secure; see docs for alternatives 
     MapVerifier verifier = new MapVerifier(); 
     verifier.getLocalSecrets().put("user", "password".toCharArray()); 

     ChallengeAuthenticator authOnGet = new ChallengeAuthenticator(context, challengeScheme, realm) { 
      @Override 
      protected int beforeHandle(Request request, Response response) { 
       if (request.getMethod() == Method.GET) 
        return super.beforeHandle(request, response); 

       response.setStatus(Status.SUCCESS_OK); 
       return CONTINUE; 
      } 
     }; 

     return authOnGet; 
    } 

    @Override 
    public Restlet createInboundRoot() { 
     ChallengeAuthenticator userResourceWithAuth = createAuthenticator(); 
     userResourceWithAuth.setNext(UserResource.class); 

     Router router = new Router(); 
     router.attach("/user", userResourceWithAuth); 

     return router; 
    } 

} 

संसाधन:

package example; 

import org.restlet.resource.Get; 
import org.restlet.resource.Post; 
import org.restlet.representation.Representation; 
import org.restlet.resource.ServerResource; 

public class UserResource extends ServerResource { 

    @Get 
    public Representation listUsers() { 
     // retrieve list of users and generate response 
     // ... 
    }  

    @Post 
    public void register(Representation entity) { 
     // handle post 
     // ... 
    } 
} 

ध्यान दें कि यह उदाहरण केवल UserResource और नहीं अन्य रूटर द्वारा नियंत्रित संसाधनों को पाने पर प्रमाणीकृत करने की नीति लागू होगी।

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