mirror of
https://github.com/moparisthebest/davmail
synced 2024-12-14 11:42:23 -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:
parent
b2ff79a8a3
commit
d4942165b4
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2488,11 +2501,11 @@ public abstract class ExchangeSession {
|
|||||||
Condition condition;
|
Condition condition;
|
||||||
if (caldavDisableTasks) {
|
if (caldavDisableTasks) {
|
||||||
condition = or(isEqualTo("instancetype", 1),
|
condition = or(isEqualTo("instancetype", 1),
|
||||||
and(isEqualTo("instancetype", 0), dateCondition));
|
and(isEqualTo("instancetype", 0), dateCondition));
|
||||||
} else {
|
} else {
|
||||||
condition = or(isNull("instancetype"),
|
condition = or(isNull("instancetype"),
|
||||||
isEqualTo("instancetype", 1),
|
isEqualTo("instancetype", 1),
|
||||||
and(isEqualTo("instancetype", 0), dateCondition));
|
and(isEqualTo("instancetype", 0), dateCondition));
|
||||||
}
|
}
|
||||||
|
|
||||||
return searchEvents(folderPath, condition);
|
return searchEvents(folderPath, condition);
|
||||||
@ -2529,11 +2542,11 @@ public abstract class ExchangeSession {
|
|||||||
Condition condition;
|
Condition condition;
|
||||||
if (caldavDisableTasks) {
|
if (caldavDisableTasks) {
|
||||||
condition = or(isEqualTo("instancetype", 1),
|
condition = or(isEqualTo("instancetype", 1),
|
||||||
and(isEqualTo("instancetype", 0), dateCondition));
|
and(isEqualTo("instancetype", 0), dateCondition));
|
||||||
} else {
|
} else {
|
||||||
condition = or(isNull("instancetype"),
|
condition = or(isNull("instancetype"),
|
||||||
isEqualTo("instancetype", 1),
|
isEqualTo("instancetype", 1),
|
||||||
and(isEqualTo("instancetype", 0), dateCondition));
|
and(isEqualTo("instancetype", 0), dateCondition));
|
||||||
}
|
}
|
||||||
|
|
||||||
return searchEvents(folderPath, condition);
|
return searchEvents(folderPath, condition);
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
@ -182,7 +180,7 @@ public class EwsExchangeSession extends ExchangeSession {
|
|||||||
email = getAliasFromLogin() + getEmailSuffixFromHostname();
|
email = getAliasFromLogin() + getEmailSuffixFromHostname();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
currentMailboxPath = "/users/" + email.toLowerCase();
|
currentMailboxPath = "/users/" + email.toLowerCase();
|
||||||
|
|
||||||
// check EWS access
|
// check EWS access
|
||||||
@ -191,18 +189,27 @@ 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 {
|
try {
|
||||||
// failover, try to retrieve EWS url from autodiscover
|
checkEndPointUrl("/ews/exchange.asmx");
|
||||||
checkEndPointUrl(getEwsUrlFromAutoDiscover());
|
|
||||||
// workaround for Exchange bug: send fake request
|
// workaround for Exchange bug: send fake request
|
||||||
internalGetFolder("");
|
internalGetFolder("");
|
||||||
} catch (IOException e2) {
|
} catch (IOException e2) {
|
||||||
// autodiscover failed and initial exception was authentication failure => throw original exception
|
LOGGER.debug(e2.getMessage());
|
||||||
if (e instanceof DavMailAuthenticationException) {
|
try {
|
||||||
throw (DavMailAuthenticationException) e;
|
// failover, try to retrieve EWS url from autodiscover
|
||||||
|
checkEndPointUrl(getEwsUrlFromAutoDiscover());
|
||||||
|
// workaround for Exchange bug: send fake request
|
||||||
|
internalGetFolder("");
|
||||||
|
} catch (IOException e3) {
|
||||||
|
// autodiscover failed and initial exception was authentication failure => throw original exception
|
||||||
|
if (e instanceof DavMailAuthenticationException) {
|
||||||
|
throw (DavMailAuthenticationException) e;
|
||||||
|
}
|
||||||
|
LOGGER.error(e2.getMessage());
|
||||||
|
throw new DavMailAuthenticationException("EXCEPTION_EWS_NOT_AVAILABLE");
|
||||||
}
|
}
|
||||||
LOGGER.error(e2.getMessage());
|
|
||||||
throw new DavMailAuthenticationException("EXCEPTION_EWS_NOT_AVAILABLE");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user