001/* 002 * This library is part of OpenCms - 003 * the Open Source Content Management System 004 * 005 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com) 006 * 007 * This library is free software; you can redistribute it and/or 008 * modify it under the terms of the GNU Lesser General Public 009 * License as published by the Free Software Foundation; either 010 * version 2.1 of the License, or (at your option) any later version. 011 * 012 * This library is distributed in the hope that it will be useful, 013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 015 * Lesser General Public License for more details. 016 * 017 * For further information about Alkacon Software GmbH & Co. KG, please see the 018 * company website: http://www.alkacon.com 019 * 020 * For further information about OpenCms, please see the 021 * project website: http://www.opencms.org 022 * 023 * You should have received a copy of the GNU Lesser General Public 024 * License along with this library; if not, write to the Free Software 025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 026 */ 027 028package org.opencms.security; 029 030import org.opencms.file.CmsObject; 031import org.opencms.main.A_CmsAuthorizationHandler; 032import org.opencms.main.CmsException; 033import org.opencms.main.CmsHttpAuthenticationSettings; 034import org.opencms.main.OpenCms; 035import org.opencms.util.CmsRequestUtil; 036import org.opencms.workplace.CmsWorkplaceManager; 037 038import java.io.IOException; 039 040import javax.servlet.http.HttpServletRequest; 041import javax.servlet.http.HttpServletResponse; 042 043import org.apache.commons.codec.binary.Base64; 044 045/** 046 * Defines default authorization methods.<p> 047 * 048 * @since 6.5.4 049 */ 050public class CmsDefaultAuthorizationHandler extends A_CmsAuthorizationHandler { 051 052 /** Basic authorization prefix constant. */ 053 public static final String AUTHORIZATION_BASIC_PREFIX = "BASIC "; 054 /** Authorization header constant. */ 055 public static final String HEADER_AUTHORIZATION = "Authorization"; 056 /** Credentials separator constant. */ 057 public static final String SEPARATOR_CREDENTIALS = ":"; 058 059 /** 060 * @see org.opencms.security.I_CmsAuthorizationHandler#getLoginFormURL(java.lang.String, java.lang.String, java.lang.String) 061 */ 062 public String getLoginFormURL(String loginFormURL, String params, String callbackURL) { 063 064 if (loginFormURL != null) { 065 066 StringBuffer fullURL = new StringBuffer(loginFormURL); 067 if (callbackURL != null) { 068 fullURL.append("?"); 069 fullURL.append(CmsWorkplaceManager.PARAM_LOGIN_REQUESTED_RESOURCE); 070 fullURL.append("="); 071 fullURL.append(callbackURL); 072 } 073 if (params != null) { 074 fullURL.append((callbackURL != null) ? "&" : "?"); 075 fullURL.append(params); 076 } 077 078 return fullURL.toString(); 079 } 080 081 return null; 082 } 083 084 /** 085 * @see I_CmsAuthorizationHandler#initCmsObject(HttpServletRequest) 086 */ 087 public CmsObject initCmsObject(HttpServletRequest request) { 088 089 // check if "basic" authorization data is provided 090 CmsObject cms = checkBasicAuthorization(request); 091 // basic authorization successful? 092 if (cms != null) { 093 try { 094 // register the session into OpenCms and 095 // return successful logged in user 096 return registerSession(request, cms); 097 } catch (CmsException e) { 098 // ignore and threat the whole login process as failed 099 } 100 } 101 // failed 102 return null; 103 } 104 105 /** 106 * @see org.opencms.security.I_CmsAuthorizationHandler#initCmsObject(javax.servlet.http.HttpServletRequest, org.opencms.security.I_CmsAuthorizationHandler.I_PrivilegedLoginAction) 107 */ 108 public CmsObject initCmsObject( 109 HttpServletRequest request, 110 I_CmsAuthorizationHandler.I_PrivilegedLoginAction loginAction) { 111 112 return initCmsObject(request); 113 } 114 115 /** 116 * @see I_CmsAuthorizationHandler#initCmsObject(HttpServletRequest, String, String) 117 */ 118 public CmsObject initCmsObject(HttpServletRequest request, String userName, String pwd) throws CmsException { 119 120 // first, try to validate the session 121 CmsObject cms = initCmsObjectFromSession(request); 122 if (cms != null) { 123 return cms; 124 } 125 // try to login with the given credentials 126 cms = OpenCms.initCmsObject(OpenCms.getDefaultUsers().getUserGuest()); 127 // this will throw an exception if login fails 128 cms.loginUser(userName, pwd); 129 // register the session into OpenCms and 130 // return successful logged in user 131 return registerSession(request, cms); 132 } 133 134 /** 135 * This method sends a request to the client to display a login form, 136 * it is needed for HTTP-Authentication.<p> 137 * 138 * @param req the client request 139 * @param res the response 140 * @param loginFormURL the full URL used for form based authentication 141 * 142 * @throws IOException if something goes wrong 143 */ 144 public void requestAuthorization(HttpServletRequest req, HttpServletResponse res, String loginFormURL) 145 throws IOException { 146 147 CmsHttpAuthenticationSettings httpAuthenticationSettings = OpenCms.getSystemInfo().getHttpAuthenticationSettings(); 148 149 if (loginFormURL == null) { 150 if (httpAuthenticationSettings.useBrowserBasedHttpAuthentication()) { 151 // HTTP basic authentication is used 152 res.setHeader( 153 CmsRequestUtil.HEADER_WWW_AUTHENTICATE, 154 "BASIC realm=\"" + OpenCms.getSystemInfo().getOpenCmsContext() + "\""); 155 res.setStatus(HttpServletResponse.SC_UNAUTHORIZED); 156 return; 157 158 } else if (httpAuthenticationSettings.getFormBasedHttpAuthenticationUri() != null) { 159 loginFormURL = httpAuthenticationSettings.getFormBasedHttpAuthenticationUri(); 160 } else { 161 LOG.error( 162 Messages.get().getBundle().key( 163 Messages.ERR_UNSUPPORTED_AUTHENTICATION_MECHANISM_1, 164 httpAuthenticationSettings.getBrowserBasedAuthenticationMechanism())); 165 res.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); 166 return; 167 } 168 } 169 170 if (LOG.isDebugEnabled()) { 171 LOG.debug( 172 Messages.get().getBundle().key( 173 Messages.LOG_AUTHENTICATE_PROPERTY_2, 174 loginFormURL, 175 req.getRequestURI())); 176 } 177 // finally redirect to the login form 178 res.sendRedirect(loginFormURL); 179 } 180 181 /** 182 * Checks if the current request contains HTTP basic authentication information in 183 * the headers, if so the user is tried to log in with this data, and on success a 184 * session is generated.<p> 185 * 186 * @param req the current HTTP request 187 * 188 * @return the authenticated cms object, or <code>null</code> if failed 189 */ 190 protected CmsObject checkBasicAuthorization(HttpServletRequest req) { 191 192 if (LOG.isDebugEnabled()) { 193 LOG.debug("Checking for basic authorization."); 194 } 195 try { 196 CmsObject cms = OpenCms.initCmsObject(OpenCms.getDefaultUsers().getUserGuest()); 197 if (OpenCms.getSystemInfo().getHttpAuthenticationSettings().getBrowserBasedAuthenticationMechanism() == null) { 198 // browser base authorization is not enabled, return Guest user CmsObject 199 if (LOG.isDebugEnabled()) { 200 LOG.debug("Browser based authorization not enabled."); 201 } 202 return cms; 203 } 204 // no user identified from the session and basic authentication is enabled 205 String auth = req.getHeader(HEADER_AUTHORIZATION); 206 if ((auth == null) || !auth.toUpperCase().startsWith(AUTHORIZATION_BASIC_PREFIX)) { 207 // no authorization data is available 208 return cms; 209 } 210 // get encoded user and password, following after "BASIC " 211 String base64Token = auth.substring(6); 212 213 // decode it, using base 64 decoder 214 String token = new String(Base64.decodeBase64(base64Token.getBytes())); 215 String username = null; 216 String password = null; 217 int pos = token.indexOf(SEPARATOR_CREDENTIALS); 218 if (pos != -1) { 219 username = token.substring(0, pos); 220 password = token.substring(pos + 1); 221 } 222 // authentication in the DB 223 cms.loginUser(username, password); 224 225 // authorization was successful create a session 226 req.getSession(true); 227 return cms; 228 } catch (CmsException e) { 229 // authorization failed 230 return null; 231 } 232 } 233}