2012-12-05 36 views
2

我有一個通過HTTPS進行通信的RESTful web服務。我想阻止其他開發人員調用API。 API位於一個數據庫前面,該數據庫從多個數據源中提取數據,所以我想控制誰使用它。使用一個登錄頁面是不是一種選擇RESTful API - 控制對API的訪問(沒有登錄頁面)

我在春天的安全性和OAuth但是看着既不提供正是我需要的。我不想在Web服務前面放置登錄頁面,而只是想在未知應用程序試圖呼叫我的服務時返回400或401 http代碼。

任何人都可以推薦我如何實現這個?

成果感謝在這個問題上的反饋。最後,我使用了一個名爲mod_authz_host的Apache模塊,它允許您將HTTP模式限制到特定的域。雖然有可能欺騙域名,但這是針對內部應用的,因此安全性要求更加寬鬆。我有下面包括一個片段與如何使用Apache模塊

包括虛擬主機

<Location /yourProtectedServices/ws> 
Order deny,allow 
Deny from all 
Allow from trusteddomain.com 
</Location> 
+1

我很好奇你是如何打開你的API來允許某人逆向工程你的應用程序? –

+0

我試圖阻止其他開發人員使用這些API調用公開的內容。 Api位於一個數據庫前面,該數據庫從多個數據源中提取數據,我寧願控制誰可以獲取數據 – cduggan

+1

好吧我在想,但這不是對您的應用程序進行逆向工程。我會換個話。 –

回答

2

內按照你的內部系統,您可以創建具有與接入訪問的應用程序列表的詳細信息令牌。只有擁有這些授權訪問令牌的開發人員/客戶端應用才能訪問。如果客戶端應用程序的源代碼可以被其他人查看,那麼這就是問題所在。

E.g.如果某人在代碼中創建了帶有訪問令牌的Android應用程序,則可以在應用程序商店中分發它時對其進行反向設計。

更新: 對於深入查看有關安全性更。 http://www.thebuzzmedia.com/designing-a-secure-rest-api-without-oauth-authentication/

+0

訪問令牌如何在客戶端和服務器之間傳遞,它只是一個隱藏在POST中的額外參數?那麼在服務器上只需從請求中提取參數並返回錯誤代碼(如果無效)? – cduggan

+0

是的,並且一定要使用https –

+0

令牌通過瀏覽器查看Javascript源代碼仍然可見。你如何解決這個問題? – cduggan

0

採取這種簡單的例子:

服務器:

@Path("/your-path") 
@RequestScoped 
public class JSONService { 

    private final static String AUTH_TOKEN = "rxxkksdfnnchshs";   

    @GET 
    @Produces(javax.ws.rs.core.MediaType.APPLICATION_JSON) 
    public Response fetchData(@QueryParam("auth_token") String auth_token) { 

     if(AUTH_TOKEN.equals(auth_token)){ 

      final String results = "result: the object what you want";    

      return Response.status(Response.Status.OK).entity(results).build(); 
     } 
     else{ 

      return Response.status(Response.Status.UNAUTHORIZED).build(); 
     } 
    } 
} 

客戶端:

@ManagedBean(name="your-bean-name") 
@RequestScoped 
public class ResteasyClient { 
    private static final String BASE_URI = "http://localhost:8080/your-context/your-rest-path";  
    private final static String AUTH_TOKEN = "rxxkksdfnnchshs"; 
    ClientRequest webResource; 
    ClientResponse response; 
    private String data; 

    public DBOResteasyClient() {   

     final String Path = "/your-path"; 
     webResource = new ClientRequest(BASE_URI+Path);    

    } 

    @Produces 
    @Named 
    public String getData(){ 
     return this.data; 
    } 

    @PostConstruct 
    public void fetchData() { 

     try{ 
      ClientRequest resource = webResource;  
      response = resource.accept(javax.ws.rs.core.MediaType.APPLICATION_JSON).queryParameter("auth_token",AUTH_TOKEN).get(ClientResponse.class); 
     }catch(Exception e){ 
      // 
     } 

     if(response.getStatus() == 200){ 
      data = (String) response.getEntity(String.class);    
     } 
    } 
} 

這個例子中使用@QueryParam( 「AUTH_TOKEN」)字符串在服務器AUTH_TOKEN獲得http請求的參數稱爲auth_token和resource.accept(javax.ws.rs.core.MediaType.APPLICATION_JSON).queryParameter(「auth_token」,AUTH_TOKEN)添加一個名爲auth_token的參數,關鍵是:服務器使用參數並將其與自己的值「(AUTH_TOKEN.equals(auth_token)」進行比較,並使用http代碼響應如何建立休眠,http 200如果接受訪問「(Response.Status。 OK)「http 401 if if not」(Response.Status.UNAUTHORIZED)「