001
014
015 package com.liferay.portal.security.auth;
016
017 import com.liferay.portal.kernel.exception.PortalException;
018 import com.liferay.portal.kernel.exception.SystemException;
019 import com.liferay.portal.kernel.log.Log;
020 import com.liferay.portal.kernel.log.LogFactoryUtil;
021 import com.liferay.portal.kernel.util.Base64;
022 import com.liferay.portal.kernel.util.CharPool;
023 import com.liferay.portal.kernel.util.GetterUtil;
024 import com.liferay.portal.kernel.util.StringUtil;
025 import com.liferay.portal.model.Company;
026 import com.liferay.portal.model.User;
027 import com.liferay.portal.service.UserLocalServiceUtil;
028 import com.liferay.portal.service.http.TunnelUtil;
029 import com.liferay.portal.util.PortalUtil;
030 import com.liferay.util.Encryptor;
031 import com.liferay.util.EncryptorException;
032
033 import java.io.IOException;
034 import java.io.ObjectOutputStream;
035
036 import java.util.Properties;
037 import java.util.StringTokenizer;
038
039 import javax.servlet.http.HttpServletRequest;
040 import javax.servlet.http.HttpServletResponse;
041
042
045 public class TunnelingServletAuthVerifier implements AuthVerifier {
046
047 @Override
048 public String getAuthType() {
049 return HttpServletRequest.BASIC_AUTH;
050 }
051
052 @Override
053 public AuthVerifierResult verify(
054 AccessControlContext accessControlContext, Properties properties)
055 throws AuthException {
056
057 AuthVerifierResult authVerifierResult = new AuthVerifierResult();
058
059 try {
060 String[] credentials = verify(accessControlContext.getRequest());
061
062 if (credentials != null) {
063 authVerifierResult.setPassword(credentials[1]);
064 authVerifierResult.setState(AuthVerifierResult.State.SUCCESS);
065 authVerifierResult.setUserId(Long.valueOf(credentials[0]));
066 }
067 }
068 catch (AuthException ae) {
069 if (_log.isDebugEnabled()) {
070 _log.debug(ae);
071 }
072
073 HttpServletResponse response = accessControlContext.getResponse();
074
075 try {
076 ObjectOutputStream objectOutputStream = new ObjectOutputStream(
077 response.getOutputStream());
078
079 objectOutputStream.writeObject(ae);
080
081 objectOutputStream.flush();
082
083 objectOutputStream.close();
084
085 authVerifierResult.setState(
086 AuthVerifierResult.State.INVALID_CREDENTIALS);
087 }
088 catch (IOException ioe) {
089 _log.error(ioe, ioe);
090
091 throw ae;
092 }
093 }
094
095 return authVerifierResult;
096 }
097
098 protected String[] verify(HttpServletRequest request) throws AuthException {
099 String authorization = request.getHeader("Authorization");
100
101 if (authorization == null) {
102 return null;
103 }
104
105 StringTokenizer st = new StringTokenizer(authorization);
106
107 if (!st.hasMoreTokens()) {
108 return null;
109 }
110
111 String basic = st.nextToken();
112
113 if (!StringUtil.equalsIgnoreCase(
114 basic, HttpServletRequest.BASIC_AUTH)) {
115
116 return null;
117 }
118
119 String encodedCredentials = st.nextToken();
120
121 if (_log.isDebugEnabled()) {
122 _log.debug("Encoded credentials " + encodedCredentials);
123 }
124
125 String decodedCredentials = new String(
126 Base64.decode(encodedCredentials));
127
128 if (_log.isDebugEnabled()) {
129 _log.debug("Decoded credentials " + decodedCredentials);
130 }
131
132 int index = decodedCredentials.indexOf(CharPool.COLON);
133
134 if (index == -1) {
135 return null;
136 }
137
138 String login = GetterUtil.getString(
139 decodedCredentials.substring(0, index));
140 String password = decodedCredentials.substring(index + 1);
141
142 String expectedPassword = null;
143
144 try {
145 expectedPassword = Encryptor.encrypt(
146 TunnelUtil.getSharedSecretKey(), login);
147 }
148 catch (EncryptorException ee) {
149 AuthException authException = new RemoteAuthException(ee);
150
151 authException.setType(AuthException.INTERNAL_SERVER_ERROR);
152
153 throw authException;
154 }
155 catch (AuthException ae) {
156 AuthException authException = new RemoteAuthException();
157
158 authException.setType(ae.getType());
159
160 throw authException;
161 }
162
163 if (!password.equals(expectedPassword)) {
164 AuthException authException = new RemoteAuthException();
165
166 authException.setType(RemoteAuthException.WRONG_SHARED_SECRET);
167
168 throw authException;
169 }
170
171 User user = null;
172
173 try {
174 user = UserLocalServiceUtil.fetchUser(GetterUtil.getLong(login));
175
176 if (user == null) {
177 Company company = PortalUtil.getCompany(request);
178
179 user = UserLocalServiceUtil.fetchUserByEmailAddress(
180 company.getCompanyId(), login);
181
182 if (user == null) {
183 user = UserLocalServiceUtil.fetchUserByScreenName(
184 company.getCompanyId(), login);
185 }
186 }
187 }
188 catch (PortalException pe) {
189 if (_log.isWarnEnabled()) {
190 _log.warn("Unable to find company", pe);
191 }
192 }
193 catch (SystemException se) {
194 if (_log.isWarnEnabled()) {
195 _log.warn("Unable to find user", se);
196 }
197 }
198
199 if (user == null) {
200 AuthException authException = new RemoteAuthException();
201
202 authException.setType(AuthException.INTERNAL_SERVER_ERROR);
203
204 throw authException;
205 }
206
207 String[] credentials = new String[2];
208
209 credentials[0] = String.valueOf(user.getUserId());
210 credentials[1] = password;
211
212 return credentials;
213 }
214
215 private static Log _log = LogFactoryUtil.getLog(
216 TunnelingServletAuthVerifier.class);
217
218 }