public String generateType3Msg( final String username, final String password, final String domain, final String workstation, final String challenge) throws NTLMEngineException { Type2Message type2Message; try { type2Message = new Type2Message(Base64.decode(challenge)); } catch (final IOException exception) { throw new NTLMEngineException("Invalid NTLM type 2 message", exception); } final int type2Flags = type2Message.getFlags(); final int type3Flags = type2Flags & (0xffffffff ^ (NtlmFlags.NTLMSSP_TARGET_TYPE_DOMAIN | NtlmFlags.NTLMSSP_TARGET_TYPE_SERVER)); final Type3Message type3Message = new Type3Message(type2Message, password, domain, username, workstation, type3Flags); return Base64.encode(type3Message.toByteArray()); }
@Override protected void processFilter( HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws Exception { // Type 1 NTLM requests from browser can (and should) always immediately // be replied to with an Type 2 NTLM response, no matter whether we're // yet logging in or whether it is much later in the session. HttpSession session = request.getSession(false); long companyId = PortalInstances.getCompanyId(request); String authorization = GetterUtil.getString(request.getHeader(HttpHeaders.AUTHORIZATION)); if (authorization.startsWith("NTLM")) { NtlmManager ntlmManager = getNtlmManager(companyId); String portalCacheKey = getPortalCacheKey(request); byte[] src = Base64.decode(authorization.substring(5)); if (src[8] == 1) { byte[] serverChallenge = new byte[8]; BigEndianCodec.putLong(serverChallenge, 0, SecureRandomUtil.nextLong()); byte[] challengeMessage = ntlmManager.negotiate(src, serverChallenge); authorization = Base64.encode(challengeMessage); response.setContentLength(0); response.setHeader(HttpHeaders.WWW_AUTHENTICATE, "NTLM " + authorization); response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); response.flushBuffer(); _portalCache.put(portalCacheKey, serverChallenge); // Interrupt filter chain, send response. Browser will // immediately post a new request. return; } byte[] serverChallenge = _portalCache.get(portalCacheKey); if (serverChallenge == null) { response.setContentLength(0); response.setHeader(HttpHeaders.WWW_AUTHENTICATE, "NTLM"); response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); response.flushBuffer(); return; } NtlmUserAccount ntlmUserAccount = null; try { ntlmUserAccount = ntlmManager.authenticate(src, serverChallenge); } catch (Exception e) { if (_log.isErrorEnabled()) { _log.error("Unable to perform NTLM authentication", e); } } finally { _portalCache.remove(portalCacheKey); } if (ntlmUserAccount == null) { response.setContentLength(0); response.setHeader(HttpHeaders.WWW_AUTHENTICATE, "NTLM"); response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); response.flushBuffer(); return; } if (_log.isDebugEnabled()) { _log.debug("NTLM remote user " + ntlmUserAccount.getUserName()); } request.setAttribute(NtlmWebKeys.NTLM_REMOTE_USER, ntlmUserAccount.getUserName()); if (session != null) { session.setAttribute(NtlmWebKeys.NTLM_USER_ACCOUNT, ntlmUserAccount); } } String path = request.getPathInfo(); if ((path != null) && path.endsWith("/login")) { NtlmUserAccount ntlmUserAccount = null; if (session != null) { ntlmUserAccount = (NtlmUserAccount) session.getAttribute(NtlmWebKeys.NTLM_USER_ACCOUNT); } if (ntlmUserAccount == null) { response.setContentLength(0); response.setHeader(HttpHeaders.WWW_AUTHENTICATE, "NTLM"); response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); response.flushBuffer(); return; } else { request.setAttribute(NtlmWebKeys.NTLM_REMOTE_USER, ntlmUserAccount.getUserName()); } } processFilter(NtlmPostFilter.class, request, response, filterChain); }