1
0
mirror of https://github.com/moparisthebest/davmail synced 2024-12-14 03:32:22 -05:00

Implement Microsoft Forefront Unified Access Gateway logon form compatibility

git-svn-id: http://svn.code.sf.net/p/davmail/code/trunk@1633 3d1905a2-6b24-0410-a738-b14d5a86fcbd
This commit is contained in:
mguessan 2011-02-28 22:31:42 +00:00
parent b2ff79a8a3
commit d4942165b4
2 changed files with 48 additions and 28 deletions

View File

@ -34,6 +34,7 @@ import org.apache.commons.httpclient.params.HttpClientParams;
import org.apache.commons.httpclient.util.URIUtil; import org.apache.commons.httpclient.util.URIUtil;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.htmlcleaner.CommentToken; import org.htmlcleaner.CommentToken;
import org.htmlcleaner.ContentToken;
import org.htmlcleaner.HtmlCleaner; import org.htmlcleaner.HtmlCleaner;
import org.htmlcleaner.TagNode; import org.htmlcleaner.TagNode;
@ -69,6 +70,7 @@ public abstract class ExchangeSession {
USER_NAME_FIELDS.add("txtUserName"); USER_NAME_FIELDS.add("txtUserName");
USER_NAME_FIELDS.add("userid"); USER_NAME_FIELDS.add("userid");
USER_NAME_FIELDS.add("SafeWordUser"); USER_NAME_FIELDS.add("SafeWordUser");
USER_NAME_FIELDS.add("user_name");
} }
protected static final Set<String> PASSWORD_FIELDS = new HashSet<String>(); protected static final Set<String> PASSWORD_FIELDS = new HashSet<String>();
@ -190,8 +192,8 @@ public abstract class ExchangeSession {
} }
} }
// avoid 401 roundtrips, only if NTLM is disabled // avoid 401 roundtrips, only if NTLM is disabled and basic authentication enabled
if (!DavGatewayHttpClientFacade.hasNTLM(httpClient)) { if (isBasicAuthentication && !DavGatewayHttpClientFacade.hasNTLM(httpClient)) {
httpClient.getParams().setParameter(HttpClientParams.PREEMPTIVE_AUTHENTICATION, true); httpClient.getParams().setParameter(HttpClientParams.PREEMPTIVE_AUTHENTICATION, true);
} }
@ -350,9 +352,9 @@ public abstract class ExchangeSession {
* @return logon method * @return logon method
* @throws IOException on error * @throws IOException on error
*/ */
protected PostMethod buildLogonMethod(HttpClient httpClient, HttpMethod initmethod) throws IOException { protected HttpMethod buildLogonMethod(HttpClient httpClient, HttpMethod initmethod) throws IOException {
PostMethod logonMethod = null; HttpMethod logonMethod = null;
// create an instance of HtmlCleaner // create an instance of HtmlCleaner
HtmlCleaner cleaner = new HtmlCleaner(); HtmlCleaner cleaner = new HtmlCleaner();
@ -376,13 +378,15 @@ public abstract class ExchangeSession {
logonMethod = new PostMethod(getAbsoluteUri(initmethod, logonMethodPath)); logonMethod = new PostMethod(getAbsoluteUri(initmethod, logonMethodPath));
List inputList = logonForm.getElementListByName("input", true); // retrieve lost inputs attached to body
List inputList = node.getElementListByName("input", true);
for (Object input : inputList) { for (Object input : inputList) {
String type = ((TagNode) input).getAttributeByName("type"); String type = ((TagNode) input).getAttributeByName("type");
String name = ((TagNode) input).getAttributeByName("name"); String name = ((TagNode) input).getAttributeByName("name");
String value = ((TagNode) input).getAttributeByName("value"); String value = ((TagNode) input).getAttributeByName("value");
if ("hidden".equalsIgnoreCase(type) && name != null && value != null) { if ("hidden".equalsIgnoreCase(type) && name != null && value != null) {
logonMethod.addParameter(name, value); ((PostMethod) logonMethod).addParameter(name, value);
} }
// custom login form // custom login form
if (USER_NAME_FIELDS.contains(name)) { if (USER_NAME_FIELDS.contains(name)) {
@ -395,7 +399,7 @@ public abstract class ExchangeSession {
logonMethod = buildLogonMethod(httpClient, newInitMethod); logonMethod = buildLogonMethod(httpClient, newInitMethod);
} else if (TOKEN_FIELDS.contains(name)) { } else if (TOKEN_FIELDS.contains(name)) {
// one time password, ask user // one time password, ask user
logonMethod.addParameter(name, DavGatewayOTPPrompt.getOneTimePassword()); ((PostMethod) logonMethod).addParameter(name, DavGatewayOTPPrompt.getOneTimePassword());
} }
} }
} else { } else {
@ -427,6 +431,15 @@ public abstract class ExchangeSession {
HttpMethod newInitMethod = DavGatewayHttpClientFacade.executeFollowRedirects(httpClient, src); HttpMethod newInitMethod = DavGatewayHttpClientFacade.executeFollowRedirects(httpClient, src);
logonMethod = buildLogonMethod(httpClient, newInitMethod); logonMethod = buildLogonMethod(httpClient, newInitMethod);
} }
} else if (content instanceof ContentToken) {
// Microsoft Forefront Unified Access Gateway redirect
String scriptValue = ((ContentToken) content).getContent();
String location = StringUtil.getToken(scriptValue, "window.location.replace(\"", "\"");
if (location != null) {
LOGGER.debug("Post logon redirect to: " + location);
logonMethod = DavGatewayHttpClientFacade.executeFollowRedirects(httpClient, location);
}
} }
} }
} }

View File

@ -55,6 +55,7 @@ public class EwsExchangeSession extends ExchangeSession {
/** /**
* Message types. * Message types.
*
* @see http://msdn.microsoft.com/en-us/library/aa565652%28v=EXCHG.140%29.aspx * @see http://msdn.microsoft.com/en-us/library/aa565652%28v=EXCHG.140%29.aspx
*/ */
protected static final Set<String> MESSAGE_TYPES = new HashSet<String>(); protected static final Set<String> MESSAGE_TYPES = new HashSet<String>();
@ -153,9 +154,6 @@ public class EwsExchangeSession extends ExchangeSession {
if (locationHeader == null || !"/ews/services.wsdl".equalsIgnoreCase(locationHeader.getValue())) { if (locationHeader == null || !"/ews/services.wsdl".equalsIgnoreCase(locationHeader.getValue())) {
throw new IOException("Ews endpoint not available at " + getMethod.getURI().toString()); throw new IOException("Ews endpoint not available at " + getMethod.getURI().toString());
} }
} catch (IOException e) {
LOGGER.debug(e.getMessage());
throw e;
} finally { } finally {
getMethod.releaseConnection(); getMethod.releaseConnection();
} }
@ -191,12 +189,20 @@ public class EwsExchangeSession extends ExchangeSession {
// workaround for Exchange bug: send fake request // workaround for Exchange bug: send fake request
internalGetFolder(""); internalGetFolder("");
} catch (IOException e) { } catch (IOException e) {
// first failover: retry with NTLM
DavGatewayHttpClientFacade.addNTLM(httpClient);
try {
checkEndPointUrl("/ews/exchange.asmx");
// workaround for Exchange bug: send fake request
internalGetFolder("");
} catch (IOException e2) {
LOGGER.debug(e2.getMessage());
try { try {
// failover, try to retrieve EWS url from autodiscover // failover, try to retrieve EWS url from autodiscover
checkEndPointUrl(getEwsUrlFromAutoDiscover()); checkEndPointUrl(getEwsUrlFromAutoDiscover());
// workaround for Exchange bug: send fake request // workaround for Exchange bug: send fake request
internalGetFolder(""); internalGetFolder("");
} catch (IOException e2) { } catch (IOException e3) {
// autodiscover failed and initial exception was authentication failure => throw original exception // autodiscover failed and initial exception was authentication failure => throw original exception
if (e instanceof DavMailAuthenticationException) { if (e instanceof DavMailAuthenticationException) {
throw (DavMailAuthenticationException) e; throw (DavMailAuthenticationException) e;
@ -205,6 +211,7 @@ public class EwsExchangeSession extends ExchangeSession {
throw new DavMailAuthenticationException("EXCEPTION_EWS_NOT_AVAILABLE"); throw new DavMailAuthenticationException("EXCEPTION_EWS_NOT_AVAILABLE");
} }
} }
}
try { try {
folderIdMap = new HashMap<String, String>(); folderIdMap = new HashMap<String, String>();
@ -221,7 +228,7 @@ public class EwsExchangeSession extends ExchangeSession {
LOGGER.error(e.getMessage(), e); LOGGER.error(e.getMessage(), e);
throw new DavMailAuthenticationException("EXCEPTION_EWS_NOT_AVAILABLE"); throw new DavMailAuthenticationException("EXCEPTION_EWS_NOT_AVAILABLE");
} }
LOGGER.debug("Current user email is " + email + ", alias is " + alias + " on "+ serverVersion); LOGGER.debug("Current user email is " + email + ", alias is " + alias + " on " + serverVersion);
} }
protected static class AutoDiscoverMethod extends PostMethod { protected static class AutoDiscoverMethod extends PostMethod {
@ -1425,7 +1432,7 @@ public class EwsExchangeSession extends ExchangeSession {
public Item getItem(String folderPath, String itemName) throws IOException { public Item getItem(String folderPath, String itemName) throws IOException {
EWSMethod.Item item = getEwsItem(folderPath, itemName); EWSMethod.Item item = getEwsItem(folderPath, itemName);
if (item == null) { if (item == null) {
throw new HttpNotFoundException(itemName + " not found in "+folderPath); throw new HttpNotFoundException(itemName + " not found in " + folderPath);
} }
String itemType = item.type; String itemType = item.type;
@ -1439,7 +1446,7 @@ public class EwsExchangeSession extends ExchangeSession {
executeMethod(getItemMethod); executeMethod(getItemMethod);
item = getItemMethod.getResponseItem(); item = getItemMethod.getResponseItem();
if (item == null) { if (item == null) {
throw new HttpNotFoundException(itemName + " not found in "+folderPath); throw new HttpNotFoundException(itemName + " not found in " + folderPath);
} }
return new Contact(item); return new Contact(item);
} else if ("CalendarItem".equals(itemType) } else if ("CalendarItem".equals(itemType)
@ -1448,7 +1455,7 @@ public class EwsExchangeSession extends ExchangeSession {
|| "Message".equals(itemType)) { || "Message".equals(itemType)) {
return new Event(item); return new Event(item);
} else { } else {
throw new HttpNotFoundException(itemName + " not found in "+folderPath); throw new HttpNotFoundException(itemName + " not found in " + folderPath);
} }
} }