2012-08-07 2 views
0

웹 응용 프로그램의 SSO 솔루션에 Waffle을 사용하고 있습니다.서블릿 인증 토큰에 도메인 이름을 삽입하십시오.

모든 것이 잘 작동하지만 약간 일부 기능을 수정하고 싶습니다 : 사용자가 SSO가 실패 도메인에 연결되어 있지 않은 경우, 현재

을 조금 인증 대화 상자가 열립니다

enter image description here

Windows 인증을 사용하려면 Domain\Username과 같은 형식의 사용자 이름이 필요하지만 대부분의 사용자는 사용자 이름 앞에 도메인을 추가하는 것을 모릅니다. 그래서 하나가 지정되지 않은 경우 기본 도메인 이름을 제공하고 싶습니다.

와플 함수에 println을 추가하고 일반 텍스트로 사용자 이름을 표시합니다 (디코딩 된 인증 토큰에 액세스 할 수있는 와플 함수를 찾았습니다. 대화 상자에 입력) :

public IWindowsSecurityContext acceptSecurityToken(String connectionId, byte[] token, String securityPackage) { 

    // I can see the passed username in the logs with this 
    System.out.println(new String(token)); 

    // I don't understand any of the JNA stuff below this comment: 
    IWindowsCredentialsHandle serverCredential = new WindowsCredentialsHandleImpl(
      null, Sspi.SECPKG_CRED_INBOUND, securityPackage); 
    serverCredential.initialize(); 

    SecBufferDesc pbServerToken = new SecBufferDesc(Sspi.SECBUFFER_TOKEN, Sspi.MAX_TOKEN_SIZE); 
    SecBufferDesc pbClientToken = new SecBufferDesc(Sspi.SECBUFFER_TOKEN, token); 

    NativeLongByReference pfClientContextAttr = new NativeLongByReference(); 

    CtxtHandle continueContext = _continueContexts.get(connectionId); 

    CtxtHandle phNewServerContext = new CtxtHandle(); 
    int rc = Secur32.INSTANCE.AcceptSecurityContext(serverCredential.getHandle(), 
      continueContext, pbClientToken, new NativeLong(Sspi.ISC_REQ_CONNECTION), 
      new NativeLong(Sspi.SECURITY_NATIVE_DREP), phNewServerContext, 
      pbServerToken, pfClientContextAttr, null); 

    WindowsSecurityContextImpl sc = new WindowsSecurityContextImpl(); 
    sc.setCredentialsHandle(serverCredential.getHandle()); 
    sc.setSecurityPackage(securityPackage); 
    sc.setSecurityContext(phNewServerContext); 

    switch (rc) 
    { 
     case W32Errors.SEC_E_OK: 
      // the security context received from the client was accepted 
      _continueContexts.remove(connectionId); 
      // if an output token was generated by the function, it must be sent to the client process 
      if (pbServerToken != null 
        && pbServerToken.pBuffers != null 
        && pbServerToken.cBuffers.intValue() == 1 
        && pbServerToken.pBuffers[0].cbBuffer.intValue() > 0) { 
       sc.setToken(pbServerToken.getBytes()); 
      } 
      sc.setContinue(false); 
      break; 
     case W32Errors.SEC_I_CONTINUE_NEEDED: 
      // the server must send the output token to the client and wait for a returned token 
      _continueContexts.put(connectionId, phNewServerContext); 
      sc.setToken(pbServerToken.getBytes()); 
      sc.setContinue(true); 
      break; 
     default: 
      sc.dispose(); 
      WindowsSecurityContextImpl.dispose(continueContext); 
      _continueContexts.remove(connectionId); 
      throw new Win32Exception(rc); 
    } 

    return sc; 
} 

그 전체 기능은 Waffle API에서 나온 것입니다. 처음에는 println 만 추가했습니다.

전달 된 사용자 이름은 임의의 바이트 문자 (ÉsR = ÍtÍö? æ¸ + Û-) 사이에이 토큰 안에 일반 텍스트로 인쇄됩니다.

나는 JNA와 자바로 전반적으로 매우 멀리 떨어져 있지만, 여기에 사용자 이름이 표시 될 수 있기 때문에이 토큰의 사용자 이름 부분에 도메인 이름을 추가하는 방법이 있어야한다고 생각했습니다. 내가 틀렸을 수도있다.

다른 아이디어는이 메서드가 전달 된 원시 byte [] 토큰에서 생성 된 pbClientToken에 도메인을 추가하는 것이 었습니다.

pbClientTokenJNA Structure object이다. 유망스럽게 보이는 Stucture 방법 writeField이 있지만 필자는 어떤 필드를 써야 하는지를 파악할 수 없습니다. Structure.getFields 메서드는 pbClientToken에서 사용할 수없는 것 같습니다.

나는 이것이 byte [] 처리 또는 JNA에 더 익숙한 사람에게는 간단한 문제라고 희망했다.

+0

@ 차단 당신은 이것에 대해 뭔가를 알고있을 것입니다. – Geronimo

답변

0

이 작업을 수행 할 수 없습니다. 이 대화 상자 뒤에서 일어나는 일은 사용자의 컴퓨터에있는 LogonUser에 대한 호출입니다. 그러면 티켓이 서버로 전송됩니다. 불행히도 서버는 동일한 도메인에 있지 않으므로 사용자 이름을 추출해도 완전히 쓸모가 없습니다.