2013-05-23 2 views
19

Java EE 응용 프로그램에서 사용자를 안정적으로 인증하는 데 사용할 수있는 옵션을 평가하는 데 시간을 할애했습니다.Java EE에 대한 RESTful 인증

아래 나열된 옵션이 장단점에 대한 진술과 함께 유효한지 제안하십시오. 인증 방법을 실용적으로 만들 수있는 세부 사항이 누락되었을 수 있습니다. 아니면

1 (다시 우리는 엄격하게 자바 EE 그래서 무 조회 인증 어떤 그것이 EE 준수하는 방법으로 수행 할 수 있습니다하지 않는 한을 얘기하고) 내가 놓친 한 또 다른 옵션이 있다고 수 있습니다 . DIGEST/BASIC 인증

<security-constraint> 
    <web-resource-collection> 
     <web-resource-name>admin</web-resource-name> 
     <url-pattern>/protected/*</url-pattern> 
    </web-resource-collection> 
    <auth-constraint> 
     <role-name>admin</role-name> 
    </auth-constraint> 
</security-constraint> 
<login-config> 
    <auth-method>DIGEST/BASIC</auth-method> 
    <realm-name>as-defined-secuity-realm</realm-name> 
</login-config> 

장점

  1. 이것은 REST 친화적 인 인증 방법입니다. AJAX 호출을 통해 인증 자격 증명을 보낼 수 있습니다. 사용자가 인증되면 브라우저는 적절한 Authorization: Basic/Digest QWxhZGRpbjpvcGVuIHNlc2FtZQ== 헤더가있는 요청을 수반합니다. 나쁜 신용 정보의 경우, 사용자는 추악한 브라우저 로그인 화면이 표시 될 것입니다. 그렇다면 BASIC/DIGEST 인증이 당신을위한 길입니다.

  2. 다이제스트의 경우 서버에 전달 된 문자열은 MD5로 암호화 된 문자열입니다.이 문자열은 Basic (사용자 : 암호 '문자열의 Base64 인코딩)보다 확실히 안전하지만 역시 decipherable입니다. 따라서 보안 측면에서 BASIC은 FORM 인증만큼 안전하며 DIGEST가 가장 안전합니다. 결론적으로 귀하의 사이트가 전적으로 HTTPS 인 경우 (예 : 전체가) HTTP를 통해 일부 리소스를 가져 오는 경우 인증 헤더가 제 3 자에게 표시되므로 BASIC/DIGEST와 함께 가면 안전합니다.

  3. 설정하기 쉽습니다.

    1. 가 로그 아웃

    단점은 구현하기가 까다 롭습니다. herehere을 참조하십시오. 사용자를 인증하는 훌륭한 AJAX 요청을 갖고 있는지 확인해야하지만 AJAX가 필요합니까? 사용자가 로그 오프하여 브라우저 로그인 창이 다시 나타나게하는 요청). 좋은 servlet 3.0 request.logout() 메소드 does not work properly in this case BTW.

  4. 세션 시간 초과는 구현하기가 매우 어렵습니다. 세션 만료가 발생하지만 (서블릿 컨테이너의 작업 임) 브라우저는 다음 요청시 인증 헤더를 보내 재 인증을 트리거합니다.
  5. 개인화 된 로그인 페이지가 없습니다. 없음.
  6. 인증 된 세션을 추적하기가 어렵습니다.

2.FORM 기반 인증

<security-constraint> 
    <web-resource-collection> 
     <web-resource-name>admin</web-resource-name> 
     <url-pattern>/protected/*</url-pattern> 
    </web-resource-collection> 
    <auth-constraint> 
     <role-name>admin</role-name> 
    </auth-constraint> 
</security-constraint> 
<login-config> 
    <auth-method>FORM</auth-method> 
    <realm-name>as-defined-security-realm</realm-name> 
    <form-login-config> 
     <form-login-page>/auth/login.html</form-login-page> 
     <form-error-page>/auth/error.html</form-error-page> 
    </form-login-config> 
</login-config> 

길고도 짧은 이야기, 사용자가 protected/* URL을 액세스하는 경우, 로그인 페이지가 는 응답 포함되어 있습니다. 따라서 사용자는 콘텐츠 대신 form-login-page 태그에 구성된 로그인 페이지를 가져올 것으로 예상합니다. 암호가 맞으면 처음에 요청한 protected/* URL로 전달됩니다 (302 페이징 영구 이동). 암호가 NOK 인 경우, 사용자는 오류 페이지로 전달됩니다 (302 페이 지 영구 이동).

장점

  1. 개인 로그인 페이지 -이 사람은
  2. 로그 오프가 쉽게 구현할 수 : 가장 인기있는 것 같다. HttpSession을 무효화하거나 request.logout() 메소드 (Servlet 3.0) 만 호출하면됩니다.
  3. 세션 시간 초과
  4. IF 및 유일한 경우 로그인 할 때 별도의 페이지가 필요하다고 받아 들인 경우 솔루션입니다.

단점

  1. REST (I 휴식 및 보관 서버 측 국가의 phylosophy에 파고하지 않을 편안하고 논쟁하지거야. 우리는 휴식 인증을 분석하고 비우호적 JAVA EE 방식 및 서버 측 상태는 인증 된 주체에 대해 항상 유지 관리됩니다. 실제로 FORM 인증을 사용하는 것이 좋지 않은 점은 브라우저간에 일관된 동작을 수행 할 수 없다는 점입니다. 또한 일부 브라우저는 AJAX 응답 기능에서 처리하는 반면 302 브라우저는 전체 페이지를 리디렉션하는 302 리디렉션 (탐색 막대의 URL 변경)으로 인해 발생합니다. 자세한 내용은 herehere입니다. 302 리다이렉트를 해결할 수 없으므로 FORM 및 REST 인증이 필요 없습니다.

3. 프로그래밍 인증

은 인증을위한 URL을 설정합니다. 이 URL 뒤에 로그인 모듈 (JAAS 방식)을 인스턴스화하고 자격 증명과 함께 HttpServletRequest.login (user, pass) 메소드를 호출하는 서블릿을 가질 수 있습니다. 로그인에 실패하면 401/403 응답을 생성해야합니다.

당신은 당신의 web.xml에서 보안 제약 조건을 지정하여 구현할 수 있습니다

<security-constraint> 
    <web-resource-collection> 
     <web-resource-name>admin</web-resource-name> 
     <url-pattern>/protected/*</url-pattern> 
    </web-resource-collection> 
    <auth-constraint> 
     <role-name>admin</role-name> 
    </auth-constraint> 
</security-constraint> 

을 단순히 발신자를 인증 편안한 서비스를 설정하는 데 필요한 서버 측에서.

@Path("/auth") 
@ApplicationPath("/rest") 
public class AuthenticationRestFacade { 

@POST 
@Path("/login") 
@Consumes(MediaType.APPLICATION_JSON) 
@Produces(MediaType.APPLICATION_JSON) 
public User login(User loginInfo, @Context HttpServletRequest request) throws LoginException, ServletException { 

    // nasty work-around for Catalina AuthenticatorBase to be able to 
    // change/create the session cookie 
    request.getSession(); 
    request.login(loginInfo.getName(), loginInfo.getPassword()); 

장점

  1. Personlized 로그인 페이지 : 여기에 몇 가지 예제 코드입니다.
  2. AJAX/REST 호환
  3. 로그 아웃 URL (컨테이너 관리)
  4. 세션 시간 초과 (A URL은 그렇게 설정되어있는 경우)
  5. 당신은 로그인 데이터 (사용자 이름, 이메일, 역할, 그룹 등을 반환 할 수 있습니다
  6. .) 응답 (당신이 성공적으로 로그인 한 후 다른 전화를 할 필요가 없기 때문에 reaaaallly 좋은)

단점에

  1. 약간의 코드 작성이 필요합니다.

    1. 당신이 세션 타임 아웃 또는 로그 아웃을 걱정하지 않는 경우 :

    는 결론 최선의 실행 가능한 옵션 401/403 응답 및 디스플레이 로그인 창을 처리 할 수 ​​있도록 응용 프로그램을 필요로 -> DIGEST

  2. 위의 코드가 작동하지 않고 로그인 페이지 (또는 모달 패널과 유사한 페이지)가 필요 없으며 인증을 위해 하나의 페이지 만 있으면됩니다. -> FORM
  3. 위의 경우 PROGRAMMATIC 접근 방식으로 세계의 모든 유연성과 호환성을 원합니다. 로그인/로그 아웃 URL을 정의해야하고 클라이언트 코드가 401/403 응답 (쉽게는 안됨)을 처리 할 수 ​​있어야합니다.

실용적인 대체 솔루션을 제안하기를 기대합니다.

무엇 에 대해 Keberos : 지금 내가 프로그래밍 방식으로 갈 싫어하기 때문에

+1

언급하지 않은 Java EE 옵션 중 하나가 JASPIC 일 수 있습니다. 이 기능은 전체 Java EE 6 프로파일에서 사용할 수 있으며 인증을 정렬하는 방법에 대해 많은 자유를줍니다. –

+0

JASPIC은 충분히 성숙하지 않았기 때문에 나는 가지 않을 것입니다. JASPIC @Arjan에 관한 좋은 튜토리얼. – victor

+0

와우,이 질문에 사랑이 없습니다. 나는 더 알고 싶다. 그래도 아주 좋은 질문입니다. – mikato

답변

0

이이 편안하고 있지만, 좋은 것입니다 여부 아마도 논쟁의 여지가 적어도 다음 사항을 해결? Windows AD와 같은 인증 서버 사용 ...

공개 키 인증서은 무엇입니까? 사용자를 식별하기 위해 클라이언트 제공 인증서에 의존하여 ...

? OpenID와 같은 타사 토큰 발급자 ...

3

제 경험상 Java EE 인증 및 권한 부여 서비스를 사용하여 시스템을 구현하는 것이 어렵습니다.이 서비스는 REST 서비스와 JSP 또는 JSF와 같은 서버 측 MVC 모두에서 작동합니다. 같은 시간. 내 모든 경험은 MVC 부분에 대한 폼 기반 인증과 REST 서비스에 대한 일종의 토큰 인증 (OAuth, Kerberos, LTPA)을 사용하는 방향으로 기울어 져있다. REST 서비스에 Form 또는 Basic 인증을 사용하는 것은 일반적으로 구현하기가 어려웠지만 우리는 그것을 수행했지만 두 프로젝트에서 제대로 작동합니다.

또한 기본 설정 서버 구현에 따라 다릅니다.