2013-03-25 38 views
6

Tôi muốn viết một servlet bao quanh một tập hợp các tài nguyên và cần bảo vệ chúng bằng xác thực HTTP cơ bản; tên người dùng/mật khẩu đã gửi sẽ được kiểm tra dựa trên cơ sở dữ liệu phụ trợ trước khi phân phối tệp.Thực hiện xác thực cơ sở HTTP trong servlet

Có ai có ví dụ nào về điều này không? Tôi đã thử mẫu tại số http://www.coderanch.com/t/352345/Servlets/java/HTTP-basic-authentication-Web-Applications nhưng vẫn giữ lại số IllegalStateException trong cuộc gọi sendError.

+0

bài servlet của bạn –

+0

tôi chỉ sử dụng mẫu trong liên kết. –

+1

@Roy, ví dụ trong bài đăng của bạn hoạt động tốt cho tôi. Tôi không chắc chắn tại sao nó đưa ra lỗi cho bạn. bạn có thể vui lòng cập nhật bài đăng của mình bằng stacktrace không? –

Trả lời

17

Dưới đây là một số mã trả về đối tượng Credential (đối tượng đậu giữ thông tin đăng nhập và mật khẩu).

public Credentials credentialsWithBasicAuthentication(HttpServletRequest req) { 
    String authHeader = req.getHeader("Authorization"); 
    if (authHeader != null) { 
     StringTokenizer st = new StringTokenizer(authHeader); 
     if (st.hasMoreTokens()) { 
      String basic = st.nextToken(); 

      if (basic.equalsIgnoreCase("Basic")) { 
       try { 
        String credentials = new String(Base64.decodeBase64(st.nextToken()), "UTF-8"); 
        LOG.debug("Credentials: " + credentials); 
        int p = credentials.indexOf(":"); 
        if (p != -1) { 
         String login = credentials.substring(0, p).trim(); 
         String password = credentials.substring(p + 1).trim(); 

         return new Credentials(login, password); 
        } else { 
         LOG.error("Invalid authentication token"); 
        } 
       } catch (UnsupportedEncodingException e) { 
        LOG.warn("Couldn't retrieve authentication", e); 
       } 
      } 
     } 
    } 

    return null; 
} 

Nó hoạt động tốt, ngay cả với một mật khẩu như sôi nổi như: & =/é $ £.

Đây là một thử nghiệm cơ bản đơn vị cho lớp, sử dụng JMock:

public void testCredentialsWithBasicAuthentication() { 
    // Setup 
    final HttpServletRequest request = context.mock(HttpServletRequest.class); 

    AuthentificationHelper helper = new AuthentificationHelper(); 
    String login = "mickael"; 
    String password = ":&=/?é$£"; 
    String base64Hash = Base64.encodeString(login + ":" + password); 
    final String authHeader = "Basic " + base64Hash; 

    // Expectations 
    context.checking(new Expectations() { 
     { 
      oneOf (request).getHeader("Authorization"); 
      will(returnValue(authHeader)); 
     } 
    }); 

    // Execute 
    Credentials credentials = helper.credentialsWithBasicAuthentication(request); 

    // Verify 
    assertNotNull(credentials); 
    assertEquals(login, credentials.getLogin()); 
    assertEquals(password, credentials.getPassword()); 

    context.assertIsSatisfied(); 
} 
+1

Một lưu ý nhỏ về việc sử dụng lớp 'StringTokenizer' được lấy từ tài liệu Java chính thức:" 'StringTokenizer' là một lớp kế thừa được giữ lại vì lý do tương thích mặc dù việc sử dụng nó không được khuyến khích trong mã mới. sử dụng phương thức 'split' của' String' hoặc gói java.util.regex thay thế. " – xonya

+0

Lớp Base64 bắt nguồn từ đâu? –

+0

Tôi đã không mã hóa với Java trong một thời gian nhưng không phải là phần Base64 của J2SE? như trong https://docs.oracle.com/javase/8/docs/api/java/util/Base64.html –

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