2012-02-04 38 views
1

我有一個基於restlet的應用程序,運行在heroku上,我想使用SSL。我啓用了基本的「piggyback」ssl選項,因此它接受ssl連接 - 幾乎在那裏!但是,我希望一些(實際上可能是全部)URL只在用戶通過ssl連接時纔有效。現在(我被告知)Heroku將SSL轉換爲非ssl調用,並將HTTP_X_FORWARDED_PROTO設置爲https,所以我認爲我需要在restlet中處理這個問題,但我不知道如何。我看到了重定向器類,但是我不清楚我是否可以使用這個類來解決這個問題。如何在Heroku上使用restlet在某些URL上強制使用SSL

注意:我以前使用GAE運行我的應用程序,它使用了一個servlet容器,所以我可以在web.xml中指定「CONFIDENTIAL」。

謝謝!

回答

2

你可以擺脫HTTP請求頭的信息,然後決定是否要拋出一個錯誤或重定向:

Form requestHeaders = (Form) this.getRequest().getAttributes().get("org.restlet.http.headers"); 

    boolean secure = false; 
    if (requestHeaders.getValues("x-forwarded-proto") != null) { 
     secure = requestHeaders.getValues("x-forwarded-proto").contains("https"); 
    } 

擴展在此您可以創建一個可以很容易地應用到一個過濾器路線。一個完整的代碼示例是on GitHub。但這裏是基本SecureFilter:

public class SecureFilter extends Filter { 

    private boolean doRedirect; 

    public SecureFilter(Context context, Restlet next) { 
     super(context); 
     doRedirect = false; 
     setNext(next); 
    } 

    public SecureFilter(Context context, Restlet next, boolean doRedirect) { 
     super(context); 
     this.doRedirect = doRedirect; 
     setNext(next); 
    } 

    public SecureFilter(Context context, Class<?> next) { 
     super(context); 
     doRedirect = false; 
     setNext(next); 
    } 

    public SecureFilter(Context context, Class<?> next, boolean doRedirect) { 
     super(context); 
     this.doRedirect = doRedirect; 
     setNext(next); 
    } 

    public boolean isDoRedirect() { 
     return doRedirect; 
    } 

    public void setDoRedirect(boolean doRedirect) { 
     this.doRedirect = doRedirect; 
    } 

    @Override 
    protected int beforeHandle(Request request, Response response) { 
     Form requestHeaders = (Form) request.getAttributes().get("org.restlet.http.headers"); 

     if ((requestHeaders.getValues("x-forwarded-proto") != null) && (requestHeaders.getValues("x-forwarded-proto").indexOf("https") != 0)) { 
      if (doRedirect) { 
       String target = "https://" + request.getHostRef().getHostDomain() + request.getResourceRef().getPath(); 
       Redirector redirector = new Redirector(getContext(), target, Redirector.MODE_CLIENT_SEE_OTHER); 
       redirector.handle(request, response); 
       return STOP; 
      } 
      else { 
       response.setStatus(Status.CLIENT_ERROR_FORBIDDEN); 
       return STOP; 
      } 
     } 

     return CONTINUE; 
    } 

} 

要使用SecureFilter,則只需將路徑/資源映射:

router.attach("/secure", new SecureFilter(getContext(), HelloSecureResource.class)); 
    router.attach("/secureWithRedirect", new SecureFilter(getContext(), HelloSecureResource.class, true)); 
+0

這是罰款處理一個或兩個電話,但我的API有至少一個一打資源,所有這些資源至少接受一種方法(大部分接受更多)。我想在一個地方做這件事,而不是在我處理電話的任何地方。 – 2012-02-06 21:28:14

+0

你知道RESTlet是否有全局攔截器/過濾器? – 2012-02-06 21:37:59

+0

這就是我要找的。它有一個重定向器類,但我不知道如何使用它來實現我想要的。也許我可以使用「org.restlet.service.Service」,但是,再次,不清楚如何。 – 2012-02-06 23:30:38

相關問題