2016-03-12 23 views
5

Tôi có một ứng dụng web Java cung cấp dịch vụ tìm kiếm và trong một số trường hợp cần kiểm tra bảo mật để có kết quả. Nếu nó quan trọng, nó được thực hiện trong Spring MVC và chạy dưới cầu cảng.Xác thực ADFS và mạo danh từ ứng dụng Java (Spring MVC under Jetty)

Tôi có một khách hàng muốn xác thực ứng dụng web để:

  • Hãy thực hiện thông qua Active Directory Federation Services (ADFS) thay vì hiện cơ chế xây dựng-in (để tránh một tên đăng nhập riêng biệt).
  • Có thể mạo danh người dùng từ xa trên máy chủ tìm kiếm, như vậy có thể thực hiện kiểm tra bảo mật thực thi một ứng dụng riêng trên máy chủ tìm kiếm (không biết gì về ADFS, nhưng có thể thực hiện kiểm tra có liên quan khi chạy với tư cách là người dùng được đề cập).

Điều này có thể, và nếu có, làm cách nào?

(Xin lỗi nếu các thuật ngữ trên thế giới Windows là một chút tắt - nó không phải là một cái gì đó tôi biết nhiều về, nhưng hy vọng ít nhất là ý định rõ ràng)


Một vài lưu ý về mảnh ghép tôi đã đã nhìn:

  1. Impersonating a user from a Java Servlet, là một câu hỏi tôi đã có một số năm trước đây bao gồm khoảng cùng một khu đất, nhưng không có yêu cầu ADFS - tôi không chắc chắn như thế nào ADFS tác động vật, nhưng Waffle (giải pháp cho câu hỏi đó) dường như không cung cấp bất kỳ hỗ trợ nào cho nó.
  2. Tôi đã xem Java application with SSO (SAML) and ADFSHow do I talk to ADFS from Java?, dường như cung cấp cách thức để xác thực ADFS, nhưng tôi không chắc chắn liệu điều đó có tương thích với mạo danh tiếp theo hay không.
  3. Tôi đã nhìn thấy http://blogs.objectsharp.com/post/2010/09/10/Converting-Claims-to-Windows-Tokens-and-User-Impersonation.aspxhttps://msdn.microsoft.com/en-au/library/ee517278.aspx nhưng tôi không chắc chắn:

    1. Nếu tôi sẽ được tiếp cận với những tuyên bố cần thiết để làm điều này nếu tôi đi theo con đường SAML hoặc OAuth trên
    2. Cho dù đó là có thể thực hiện điều đó từ bên trong Java
  4. tôi nghĩ thứ hai (mạo danh) một phần là gần giống như Impersonating ASP.NET claims identity to windows identity, ngoại trừ việc tôi muốn làm điều đó từ bên trong Java chứ không phải là Net.

Trả lời

3

Bạn không đề cập đến phiên bản ADFS?

Bạn có ba lựa chọn:

  • WS-Fed
  • SAML
  • OAuth2

Trong thế giới Java, SAML thường được sử dụng. Điều này ngụ ý một chồng SAML.

Liên kết SO ở trên có câu trả lời từ tôi với các liên kết đến danh sách các ngăn xếp SAML.

Vì bạn đang sử dụng Spring nên Spring Security có vẻ phù hợp.

Spring Security SAML Extension

ADFS hiện không hỗ trợ OpenID Connect trong đó quy định OAuth ra.

Có - Spring Security cung cấp cho bạn danh sách các xác nhận quyền sở hữu được tạo bởi ADFS.

ADFS cung cấp mạo danh qua Identity Delegation.

Thật không may, điều này thường được thực hiện thông qua WCF và WIF (cả hai cấu trúc .NET).

3

Tôi có ứng dụng tương tự là ứng dụng khách Swing chứ không phải ứng dụng web, nhưng quá trình này phải tương tự. Nó cần phải gửi các truy vấn theo một vai trò giả định bằng cách sử dụng một API AWS sau khi xác thực đầu tiên với một máy chủ ADFS tại chỗ. Trong môi trường của chúng ta, ADFS đã được cấu hình để đưa ra các xác nhận SAML và AWS đã được cấu hình để nhận ra chúng. Vì vậy, đây là những gì tôi làm:

  1. Khi được yêu cầu, ứng dụng sẽ nhắc người dùng xác nhận mạng thông thường và chúng được sử dụng để yêu cầu xác nhận SAML từ ADFS. Tôi sử dụng Apache HttpClient để thực hiện cuộc gọi:

    private String getAdfsResponse(String username, String password) throws Exception { 
    
    log.debug("Trying to log onto ADFS server for {}", username); 
    
    // Lax redirect policy is needed so that all HTTP 302 redirects are followed after hitting the initial ADFS URL. 
    try (CloseableHttpClient httpClient = HttpClientBuilder.create().setRedirectStrategy(new LaxRedirectStrategy()).build()) { 
    
        HttpUriRequest login = RequestBuilder.post() 
          .setUri(new URI(ADFS_URL)) 
          .addParameter("UserName", username) 
          .addParameter("Password", password) 
          .build(); 
    
        CloseableHttpResponse response = httpClient.execute(login); 
    
        if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { 
    
         HttpEntity responseEntity = response.getEntity(); 
         String adfsResponse = EntityUtils.toString(responseEntity, "UTF-8"); 
         log.debug("ADFS server responded with {}", adfsResponse); 
         return adfsResponse; 
    
        } else { 
    
         throw new Exception("ADFS server responded with " + response.getStatusLine()); 
    
        } 
    } 
    } 
    
  2. Nếu các thông tin được xác nhận, ADFS trả về một phản ứng SAML trông giống như một hình thức HTML nhưng chứa một yếu tố input với một cặp SAMLResponse tên/giá trị.

  3. Khi thuộc tính SAMLResponsevalue được giải mã base64, nó sẽ chứa xác nhận SAML. Đối với AWS, tôi cần trích xuất một số thông tin vai trò và tôi sử dụng thông tin này, cùng với đầy đủ SAMLResponse, để gọi AWS STS (dịch vụ mã thông báo bảo mật). Nếu tất cả đều OK với AWS, tôi nhận được một bộ thông tin xác thực bảo mật tạm thời mà tôi có thể sử dụng cho các truy vấn mà tôi thực sự muốn thực hiện. Toàn bộ chuyến đi vòng được mô tả trong http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_saml.html

Tất cả điều này phụ thuộc vào ADFS và bên kia là SAML cấu hình, và cho bên kia để cung cấp một API phù hợp cho phép bạn giả định một vai trò đặc biệt về phía họ. Đây có phải là thứ bạn đang đối mặt không?

+0

Tôi nghĩ cốt lõi của vấn đề của tôi là bên kia không hỗ trợ điều này, vì vậy cách chúng tôi tương tác với nó đến nay là bằng cách mạo danh người dùng từ xa với CreateProcessAsUser (https://msdn.microsoft.com /en-au/library/windows/desktop/ms682429(v=vs.85).aspx) thông qua JNI, nhưng trong ADFS/SAML thế giới, nó không rõ ràng làm thế nào tôi sẽ nhận được mã thông báo mà chức năng cần. –

Các vấn đề liên quan