LEFT | RIGHT |
1 // Copyright 2012 Google Inc. All Rights Reserved. | 1 // Copyright 2012 Google Inc. All Rights Reserved. |
2 // | 2 // |
3 // Licensed under the Apache License, Version 2.0 (the "License"); | 3 // Licensed under the Apache License, Version 2.0 (the "License"); |
4 // you may not use this file except in compliance with the License. | 4 // you may not use this file except in compliance with the License. |
5 // You may obtain a copy of the License at | 5 // You may obtain a copy of the License at |
6 // | 6 // |
7 // http://www.apache.org/licenses/LICENSE-2.0 | 7 // http://www.apache.org/licenses/LICENSE-2.0 |
8 // | 8 // |
9 // Unless required by applicable law or agreed to in writing, software | 9 // Unless required by applicable law or agreed to in writing, software |
10 // distributed under the License is distributed on an "AS IS" BASIS, | 10 // distributed under the License is distributed on an "AS IS" BASIS, |
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 // See the License for the specific language governing permissions and | 12 // See the License for the specific language governing permissions and |
13 // limitations under the License. | 13 // limitations under the License. |
| 14 |
14 package com.google.enterprise.adaptor.sharepoint; | 15 package com.google.enterprise.adaptor.sharepoint; |
15 | 16 |
16 import com.google.common.annotations.VisibleForTesting; | 17 import com.google.common.annotations.VisibleForTesting; |
17 import com.microsoft.schemas.sharepoint.soap.authentication.AuthenticationMode; | 18 import com.microsoft.schemas.sharepoint.soap.authentication.AuthenticationMode; |
18 import com.microsoft.schemas.sharepoint.soap.authentication.AuthenticationSoap; | 19 import com.microsoft.schemas.sharepoint.soap.authentication.AuthenticationSoap; |
19 import com.microsoft.schemas.sharepoint.soap.authentication.LoginErrorCode; | 20 import com.microsoft.schemas.sharepoint.soap.authentication.LoginErrorCode; |
20 import com.microsoft.schemas.sharepoint.soap.authentication.LoginResult; | 21 import com.microsoft.schemas.sharepoint.soap.authentication.LoginResult; |
21 import java.io.IOException; | 22 import java.io.IOException; |
22 import java.util.Collections; | 23 import java.util.Collections; |
23 import java.util.List; | 24 import java.util.List; |
24 import java.util.Map; | 25 import java.util.Map; |
25 import java.util.concurrent.CopyOnWriteArrayList; | 26 import java.util.concurrent.CopyOnWriteArrayList; |
26 import java.util.concurrent.ScheduledExecutorService; | 27 import java.util.concurrent.ScheduledExecutorService; |
27 import java.util.concurrent.TimeUnit; | 28 import java.util.concurrent.TimeUnit; |
28 import java.util.logging.Level; | 29 import java.util.logging.Level; |
29 import java.util.logging.Logger; | 30 import java.util.logging.Logger; |
30 | 31 |
31 import javax.xml.ws.BindingProvider; | 32 import javax.xml.ws.BindingProvider; |
| 33 import javax.xml.ws.WebServiceException; |
32 import javax.xml.ws.handler.MessageContext; | 34 import javax.xml.ws.handler.MessageContext; |
33 | 35 |
34 | 36 |
35 /** | 37 /** |
36 * | |
37 * Helper class to handle forms authentication. | 38 * Helper class to handle forms authentication. |
38 */ | 39 */ |
39 class FormsAuthenticationHandler { | 40 class FormsAuthenticationHandler { |
40 /** SharePoint's namespace. */ | 41 /** SharePoint's namespace. */ |
41 private static final String XMLNS | 42 private static final String XMLNS |
42 = "http://schemas.microsoft.com/sharepoint/soap/"; | 43 = "http://schemas.microsoft.com/sharepoint/soap/"; |
43 ·· | 44 ·· |
44 private static final Logger log | 45 private static final Logger log |
45 = Logger.getLogger(FormsAuthenticationHandler.class.getName()); | 46 = Logger.getLogger(FormsAuthenticationHandler.class.getName()); |
46 // Default time out for forms authentication with .NET is 30 mins | 47 // Default time out for forms authentication with .NET is 30 mins |
47 private static final long DEFAULT_COOKIE_TIMEOUT_SECONDS = 30 * 60; | 48 private static final long DEFAULT_COOKIE_TIMEOUT_SECONDS = 30 * 60; |
48 | 49 |
49 private final String userName; | 50 private final String userName; |
50 private final String password; | 51 private final String password; |
51 private final ScheduledExecutorService executor; | 52 private final ScheduledExecutorService executor; |
52 private final Runnable refreshRunnable = new RefreshRunnable();·· | 53 private final Runnable refreshRunnable = new RefreshRunnable();·· |
53 private final List<String> authenticationCookiesList· | 54 private final List<String> authenticationCookiesList· |
54 = new CopyOnWriteArrayList<String>(); | 55 = new CopyOnWriteArrayList<String>(); |
55 private AuthenticationMode authenticationMode; | 56 private AuthenticationMode authenticationMode; |
56 private final AuthenticationSoap authenticationClient; | 57 private final AuthenticationSoap authenticationClient; |
57 ·· | 58 ·· |
58 @VisibleForTesting···· | 59 @VisibleForTesting···· |
59 FormsAuthenticationHandler(String virtualServer, | 60 FormsAuthenticationHandler(String userName, String password, |
60 String userName, String password, ScheduledExecutorService executor, | 61 ScheduledExecutorService executor, |
61 AuthenticationSoap authenticationClient) {··· | 62 AuthenticationSoap authenticationClient) { |
| 63 if (userName == null || password == null || executor == null ||· |
| 64 authenticationClient == null) { |
| 65 throw new NullPointerException(); |
| 66 } |
62 this.userName = userName; | 67 this.userName = userName; |
63 this.password = password;··· | 68 this.password = password;··· |
64 this.executor = executor; | 69 this.executor = executor; |
65 this.authenticationClient = authenticationClient; | 70 this.authenticationClient = authenticationClient; |
66 }·· | 71 }·· |
67 | 72 |
68 public List<String> getAuthenticationCookies() { | 73 public List<String> getAuthenticationCookies() { |
69 return Collections.unmodifiableList(authenticationCookiesList); | 74 return Collections.unmodifiableList(authenticationCookiesList); |
70 } | 75 } |
71 ·· | 76 ·· |
72 public boolean isFormsAuthentication() { | 77 public boolean isFormsAuthentication() { |
73 return authenticationMode == AuthenticationMode.FORMS; | 78 return authenticationMode == AuthenticationMode.FORMS; |
74 } | 79 } |
75 ·· | 80 ·· |
76 private void refreshCookies() throws IOException { | 81 private void refreshCookies() throws IOException { |
77 log.log(Level.FINE, "AuthenticationMode = {0}", authenticationMode); | 82 log.log(Level.FINE, "AuthenticationMode = {0}", authenticationMode); |
78 if (authenticationMode != AuthenticationMode.FORMS) { | 83 if (authenticationMode != AuthenticationMode.FORMS) { |
79 return; | 84 return; |
80 } | 85 } |
81 ···· | 86 ···· |
82 LoginResult result = null; | 87 LoginResult result; |
83 try { | 88 try { |
84 result = authenticationClient.login(userName, password); | 89 result = authenticationClient.login(userName, password); |
85 } catch (Exception ex) { | 90 } catch (WebServiceException ex) { |
86 log.log(Level.WARNING, | 91 log.log(Level.WARNING, |
87 "Possible SP2013 environment with windows authentication", ex); | 92 "Possible SP2013 environment with windows authentication", ex); |
88 authenticationMode = AuthenticationMode.WINDOWS; | 93 authenticationMode = AuthenticationMode.WINDOWS; |
89 return; | 94 return; |
90 } | 95 } |
91 log.log(Level.FINE,· | 96 log.log(Level.FINE,· |
92 "Login Cookie Expiration in = {0}", result.getTimeoutSeconds()); | 97 "Login Cookie Expiration in = {0}", result.getTimeoutSeconds()); |
93 if (result.getErrorCode() != LoginErrorCode.NO_ERROR) { | 98 if (result.getErrorCode() != LoginErrorCode.NO_ERROR) { |
94 log.log(Level.WARNING, | 99 throw new IOException("Forms authentication failed with authentication " |
95 "Login result error Code = {0}", result.getErrorCode()); | 100 + "web service with Error Code " + result.getErrorCode()); |
96 throw new IOException( | |
97 "Forms authentication failed with authentication web service"); | |
98 } | 101 } |
| 102 @SuppressWarnings("unchecked") |
99 Map<String, Object> responseHeaders | 103 Map<String, Object> responseHeaders |
100 = (Map<String, Object>) ((BindingProvider) authenticationClient) | 104 = (Map<String, Object>) ((BindingProvider) authenticationClient) |
101 .getResponseContext().get(MessageContext.HTTP_RESPONSE_HEADERS); | 105 .getResponseContext().get(MessageContext.HTTP_RESPONSE_HEADERS); |
102 log.log(Level.FINEST, "Response headers: {0}", responseHeaders); | 106 log.log(Level.FINEST, "Response headers: {0}", responseHeaders); |
| 107 @SuppressWarnings("unchecked") |
103 String cookies = ((List<String>) responseHeaders.get("Set-cookie")).get(0); | 108 String cookies = ((List<String>) responseHeaders.get("Set-cookie")).get(0); |
104 if (authenticationCookiesList.isEmpty()) { | 109 if (authenticationCookiesList.isEmpty()) { |
105 authenticationCookiesList.add(cookies); | 110 authenticationCookiesList.add(cookies); |
106 } else { | 111 } else { |
107 authenticationCookiesList.set(0, cookies); | 112 authenticationCookiesList.set(0, cookies); |
108 } | 113 } |
109 long cookieTimeOut = (result.getTimeoutSeconds() == null) ?· | 114 long cookieTimeOut = (result.getTimeoutSeconds() == null) ?· |
110 DEFAULT_COOKIE_TIMEOUT_SECONDS : result.getTimeoutSeconds(); | 115 DEFAULT_COOKIE_TIMEOUT_SECONDS : result.getTimeoutSeconds(); |
111 | 116 |
112 long rerunAfter = (cookieTimeOut + 1) / 2; | 117 long rerunAfter = (cookieTimeOut + 1) / 2; |
113 executor.schedule(refreshRunnable, rerunAfter, TimeUnit.SECONDS); | 118 executor.schedule(refreshRunnable, rerunAfter, TimeUnit.SECONDS); |
114 log.log(Level.FINEST, | 119 log.log(Level.FINEST, |
115 "Authentication Cookie is {0}", authenticationCookiesList);··· | 120 "Authentication Cookie is {0}", authenticationCookiesList);··· |
116 } | 121 } |
117 · | 122 · |
118 public void start() throws IOException { | 123 public void start() throws IOException { |
119 authenticationMode = authenticationClient.mode(); | 124 authenticationMode = authenticationClient.mode(); |
120 refreshCookies(); | 125 refreshCookies(); |
121 } | 126 } |
122 | 127 |
123 private class RefreshRunnable implements Runnable { | 128 private class RefreshRunnable implements Runnable { |
124 @Override | 129 @Override |
125 public void run() { | 130 public void run() { |
126 try { | 131 try { |
127 refreshCookies(); | 132 refreshCookies(); |
128 } catch(Exception ex) { | 133 } catch(IOException ex) { |
129 log.log(Level.WARNING,· | 134 log.log(Level.WARNING,· |
130 "Error refreshing forms authentication cookies", ex);········ | 135 "Error refreshing forms authentication cookies", ex);········ |
131 executor.schedule(this, 5, TimeUnit.MINUTES); | 136 executor.schedule(this, 5, TimeUnit.MINUTES); |
132 } | 137 } |
133 } | 138 } |
134 } | 139 } |
135 } | 140 } |
LEFT | RIGHT |