use of com.zimbra.cs.account.AuthToken in project zm-mailbox by Zimbra.
the class ZimbraAuthenticator method validateRequest.
@Override
public Authentication validateRequest(ServletRequest req, ServletResponse resp, boolean mandatory) throws ServerAuthException {
if (mandatory && req instanceof HttpServletRequest) {
HttpServletRequest httpReq = (HttpServletRequest) req;
//we want to just ignore rather than potentially flooding auth provider (which may be external)
if (PathMap.match(urlPattern, httpReq.getRequestURI())) {
Cookie[] cookies = httpReq.getCookies();
if (cookies != null) {
for (Cookie cookie : cookies) {
if (ZimbraCookie.authTokenCookieName(true).equalsIgnoreCase(cookie.getName()) || ZimbraCookie.authTokenCookieName(false).equalsIgnoreCase(cookie.getName())) {
String encoded = cookie.getValue();
AuthToken token;
try {
token = AuthProvider.getAuthToken(encoded);
Account authAcct = AuthProvider.validateAuthToken(Provisioning.getInstance(), token, false);
if (authAcct != null) {
if (_loginService instanceof ZimbraLoginService) {
UserIdentity user = ((ZimbraLoginService) _loginService).makeUserIdentity(authAcct.getMail());
ZimbraLog.security.debug("Auth token validated");
return new UserAuthentication(getAuthMethod(), user);
} else {
ZimbraLog.security.warn("Misconfigured? _loginService not ZimbraLoginService");
assert (false);
}
}
} catch (AuthTokenException e) {
ZimbraLog.security.error("Unable to authenticate due to AuthTokenException", e);
} catch (ServiceException e) {
ZimbraLog.security.error("Unable to authenticate due to ServiceException", e);
}
}
}
ZimbraLog.security.debug("no valid auth token, fallback to basic");
}
}
}
return super.validateRequest(req, resp, mandatory);
}
use of com.zimbra.cs.account.AuthToken in project zm-mailbox by Zimbra.
the class UserServletUtil method getAccount.
// public synchronized static void addFormatter(Formatter f) {
// mFormatters.put(f.getType(), f);
// for (String mimeType : f.getDefaultMimeTypes())
// mDefaultFormatters.put(mimeType, f);
// }
//
// public Formatter getFormatter(String type) {
// return mFormatters.get(type);
// }
public static void getAccount(UserServletContext context) throws IOException, ServletException, UserServletException {
try {
boolean isAdminRequest = AuthUtil.isAdminRequest(context.req);
// check cookie or access key
if (context.cookieAuthAllowed() || AuthProvider.allowAccessKeyAuth(context.req, context.getServlet())) {
try {
AuthToken at = AuthProvider.getAuthToken(context.req, isAdminRequest);
if (at != null) {
if (at.isZimbraUser()) {
if (!at.isRegistered()) {
throw new UserServletException(HttpServletResponse.SC_UNAUTHORIZED, L10nUtil.getMessage(MsgKey.errMustAuthenticate, context.req));
}
try {
context.setAuthAccount(AuthProvider.validateAuthToken(Provisioning.getInstance(), at, false));
} catch (ServiceException e) {
throw new UserServletException(HttpServletResponse.SC_UNAUTHORIZED, L10nUtil.getMessage(MsgKey.errMustAuthenticate, context.req));
}
context.cookieAuthHappened = true;
context.authToken = at;
return;
} else {
if (at.isExpired()) {
throw new UserServletException(HttpServletResponse.SC_UNAUTHORIZED, L10nUtil.getMessage(MsgKey.errMustAuthenticate, context.req));
}
context.setAuthAccount(new GuestAccount(at));
// pretend that we basic authed
context.basicAuthHappened = true;
context.authToken = at;
return;
}
}
} catch (AuthTokenException e) {
// bug 35917: malformed auth token means auth failure
throw new UserServletException(HttpServletResponse.SC_UNAUTHORIZED, L10nUtil.getMessage(MsgKey.errMustAuthenticate, context.req));
}
}
// check query string
if (context.queryParamAuthAllowed()) {
String auth = context.params.get(ZimbraServlet.QP_ZAUTHTOKEN);
if (auth == null)
// not sure who uses this parameter; zauthtoken is preferred
auth = context.params.get(UserServlet.QP_AUTHTOKEN);
if (auth != null) {
try {
// Only supported by ZimbraAuthProvider
AuthToken at = AuthProvider.getAuthToken(auth);
try {
context.setAuthAccount(AuthProvider.validateAuthToken(Provisioning.getInstance(), at, false));
context.qpAuthHappened = true;
context.authToken = at;
return;
} catch (ServiceException e) {
throw new UserServletException(HttpServletResponse.SC_UNAUTHORIZED, L10nUtil.getMessage(MsgKey.errMustAuthenticate, context.req));
}
} catch (AuthTokenException e) {
// bug 35917: malformed auth token means auth failure
throw new UserServletException(HttpServletResponse.SC_UNAUTHORIZED, L10nUtil.getMessage(MsgKey.errMustAuthenticate, context.req));
}
}
}
// fallback to basic auth
if (context.basicAuthAllowed()) {
context.setAuthAccount(AuthUtil.basicAuthRequest(context.req, context.resp, context.servlet, false));
if (context.getAuthAccount() != null) {
context.basicAuthHappened = true;
context.authToken = AuthProvider.getAuthToken(context.getAuthAccount(), isAdminRequest);
// send cookie back if need be.
if (context.setCookie()) {
boolean secureCookie = context.req.getScheme().equals("https");
context.authToken.encode(context.resp, isAdminRequest, secureCookie);
}
}
// always return
return;
}
// there is no credential at this point. assume anonymous public access and continue.
} catch (ServiceException e) {
throw new ServletException(e);
}
}
use of com.zimbra.cs.account.AuthToken in project zm-mailbox by Zimbra.
the class DavServlet method service.
@Override
public void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ZimbraLog.clearContext();
addRemoteIpToLoggingContext(req);
ZimbraLog.addUserAgentToContext(req.getHeader(DavProtocol.HEADER_USER_AGENT));
//bug fix - send 400 for Range requests
String rangeHeader = req.getHeader(DavProtocol.HEADER_RANGE);
if (null != rangeHeader) {
sendError(resp, HttpServletResponse.SC_BAD_REQUEST, "Range header not supported", null, Level.debug);
return;
}
RequestType rtype = getAllowedRequestType(req);
ZimbraLog.dav.debug("Allowable request types %s", rtype);
if (rtype == RequestType.none) {
sendError(resp, HttpServletResponse.SC_NOT_ACCEPTABLE, "Not an allowed request type", null, Level.debug);
return;
}
logRequestInfo(req);
Account authUser = null;
DavContext ctxt;
try {
AuthToken at = AuthProvider.getAuthToken(req, false);
if (at != null && (at.isExpired() || !at.isRegistered())) {
at = null;
}
if (at != null && (rtype == RequestType.both || rtype == RequestType.authtoken)) {
authUser = Provisioning.getInstance().get(AccountBy.id, at.getAccountId());
} else if (at == null && (rtype == RequestType.both || rtype == RequestType.password)) {
AuthUtil.AuthResult result = AuthUtil.basicAuthRequest(req, resp, true, this);
if (result.sendErrorCalled) {
logResponseInfo(resp);
return;
}
authUser = result.authorizedAccount;
}
if (authUser == null) {
try {
sendError(resp, HttpServletResponse.SC_UNAUTHORIZED, "Authentication failed", null, Level.debug);
} catch (Exception e) {
}
return;
}
ZimbraLog.addToContext(ZimbraLog.C_ANAME, authUser.getName());
ctxt = new DavContext(req, resp, authUser);
} catch (AuthTokenException e) {
sendError(resp, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "error getting authenticated user", e);
return;
} catch (ServiceException e) {
sendError(resp, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "error getting authenticated user", e);
return;
}
DavMethod method = sMethods.get(req.getMethod());
if (method == null) {
setAllowHeader(resp);
sendError(resp, HttpServletResponse.SC_METHOD_NOT_ALLOWED, "Not an allowed method", null, Level.debug);
return;
}
long t0 = System.currentTimeMillis();
CacheStates cache = null;
try {
if (ZimbraLog.dav.isDebugEnabled()) {
try {
Upload upload = ctxt.getUpload();
if (upload.getSize() > 0 && upload.getContentType().startsWith("text")) {
if (ZimbraLog.dav.isDebugEnabled()) {
StringBuilder logMsg = new StringBuilder("REQUEST\n").append(new String(ByteUtil.readInput(upload.getInputStream(), -1, 20480), "UTF-8"));
ZimbraLog.dav.debug(logMsg.toString());
}
}
} catch (DavException de) {
throw de;
} catch (Exception e) {
ZimbraLog.dav.debug("ouch", e);
}
}
cache = checkCachedResponse(ctxt, authUser);
if (!ctxt.isResponseSent() && !isProxyRequest(ctxt, method)) {
method.checkPrecondition(ctxt);
method.handle(ctxt);
method.checkPostcondition(ctxt);
if (!ctxt.isResponseSent()) {
resp.setStatus(ctxt.getStatus());
}
}
if (!ctxt.isResponseSent()) {
logResponseInfo(resp);
}
} catch (DavException e) {
if (e.getCause() instanceof MailServiceException.NoSuchItemException || e.getStatus() == HttpServletResponse.SC_NOT_FOUND)
ZimbraLog.dav.info(ctxt.getUri() + " not found");
else if (e.getStatus() == HttpServletResponse.SC_MOVED_TEMPORARILY || e.getStatus() == HttpServletResponse.SC_MOVED_PERMANENTLY)
ZimbraLog.dav.info("sending redirect");
try {
if (e.isStatusSet()) {
resp.setStatus(e.getStatus());
if (e.hasErrorMessage())
e.writeErrorMsg(resp.getOutputStream());
if (ZimbraLog.dav.isDebugEnabled()) {
ZimbraLog.dav.info("sending http error %d because: %s", e.getStatus(), e.getMessage(), e);
} else {
ZimbraLog.dav.info("sending http error %d because: %s", e.getStatus(), e.getMessage());
}
if (e.getCause() != null)
ZimbraLog.dav.debug("exception: ", e.getCause());
} else {
sendError(resp, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "error handling method " + method.getName(), e);
}
} catch (IllegalStateException ise) {
ZimbraLog.dav.debug("can't write error msg", ise);
}
} catch (ServiceException e) {
if (e instanceof MailServiceException.NoSuchItemException) {
sendError(resp, HttpServletResponse.SC_NOT_FOUND, ctxt.getUri() + " not found", null, Level.info);
return;
}
sendError(resp, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "error handling method " + method.getName(), e);
} catch (Exception e) {
try {
sendError(resp, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "error handling method " + method.getName(), e);
} catch (Exception ex) {
}
} finally {
long t1 = System.currentTimeMillis();
ZimbraLog.dav.info("DavServlet operation " + method.getName() + " to " + req.getPathInfo() + " (depth: " + ctxt.getDepth().name() + ") finished in " + (t1 - t0) + "ms");
if (cache != null)
cacheCleanUp(ctxt, cache);
ctxt.cleanup();
}
}
use of com.zimbra.cs.account.AuthToken in project zm-mailbox by Zimbra.
the class Auth method needTwoFactorAuth.
private Element needTwoFactorAuth(Account account, TwoFactorAuth auth, ZimbraSoapContext zsc) throws ServiceException {
/* two cases here:
* 1) the user needs to provide a two-factor code.
* in this case, the server returns a two-factor auth token in the response header that the client
* must send back, along with the code, in order to finish the authentication process.
* 2) the user needs to set up two-factor auth.
* this can happen if it's required for the account but the user hasn't received a secret yet.
*/
if (!auth.twoFactorAuthEnabled()) {
throw AccountServiceException.TWO_FACTOR_SETUP_REQUIRED();
} else {
Element response = zsc.createElement(AccountConstants.AUTH_RESPONSE);
AuthToken twoFactorToken = AuthProvider.getAuthToken(account, Usage.TWO_FACTOR_AUTH);
response.addUniqueElement(AccountConstants.E_TWO_FACTOR_AUTH_REQUIRED).setText("true");
response.addAttribute(AccountConstants.E_LIFETIME, twoFactorToken.getExpires() - System.currentTimeMillis(), Element.Disposition.CONTENT);
twoFactorToken.encodeAuthResp(response, false);
response.addUniqueElement(AccountConstants.E_TRUSTED_DEVICES_ENABLED).setText(account.isFeatureTrustedDevicesEnabled() ? "true" : "false");
return response;
}
}
use of com.zimbra.cs.account.AuthToken in project zm-mailbox by Zimbra.
the class GetDomainInfo method handle.
@Override
public Element handle(Element request, Map<String, Object> context) throws ServiceException {
ZimbraSoapContext lc = getZimbraSoapContext(context);
Provisioning prov = Provisioning.getInstance();
AuthToken at = lc.getAuthToken();
boolean hasAuth = at != null;
boolean applyConfig = request.getAttributeBool(AdminConstants.A_APPLY_CONFIG, true);
Element d = request.getElement(AdminConstants.E_DOMAIN);
String key = d.getAttribute(AdminConstants.A_BY);
String value = d.getText();
Key.DomainBy domainBy = Key.DomainBy.fromString(key);
Domain domain = prov.getDomain(domainBy, value, true);
Element response = lc.createElement(AdminConstants.GET_DOMAIN_INFO_RESPONSE);
if (domain == null && domainBy != Key.DomainBy.name && domainBy != Key.DomainBy.virtualHostname) {
// domain not found, and we don't have info for walking up sub domains
// return attributes on global config
toXML(response, prov.getConfig(), applyConfig, hasAuth);
} else {
if (domain == null) {
if (domainBy == Key.DomainBy.virtualHostname)
domain = prov.getDomain(Key.DomainBy.name, value, true);
if (domain == null)
domain = findDomain(prov, value);
}
if (domain != null)
toXML(response, domain, applyConfig, hasAuth);
else
toXML(response, prov.getConfig(), applyConfig, hasAuth);
}
return response;
}
Aggregations