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