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