001/* 002// This software is subject to the terms of the Eclipse Public License v1.0 003// Agreement, available at the following URL: 004// http://www.eclipse.org/legal/epl-v10.html. 005// You must accept the terms of that agreement to use this software. 006// 007// Copyright (C) 2011-2011 Pentaho and others 008// All Rights Reserved. 009*/ 010package mondrian.xmla.impl; 011 012import mondrian.xmla.*; 013 014import org.w3c.dom.Element; 015 016import java.util.Map; 017import javax.servlet.ServletConfig; 018import javax.servlet.ServletException; 019import javax.servlet.http.HttpServletRequest; 020import javax.servlet.http.HttpServletResponse; 021 022/** 023 * This is an abstract implementation of {@link XmlaRequestCallback} 024 * specialized in authenticating the requests coming in. Subclasses are 025 * only required to implement {@link #authenticate(String, String, String)}. 026 * 027 * <p>Once implemented, you only need to register your class using the XMLA 028 * servlet config, within your web.xml descriptor. 029 * 030 * @author LBoudreau 031 */ 032public abstract class AuthenticatingXmlaRequestCallback 033 implements XmlaRequestCallback 034{ 035 public String generateSessionId(Map<String, Object> context) { 036 // We don't want to override the session ID generation algorithm. 037 return null; 038 } 039 040 public void init(ServletConfig servletConfig) throws ServletException { 041 // Nothing to initialize here. Subclasses can override 042 // this if they wish. 043 } 044 045 public void postAction( 046 HttpServletRequest request, 047 HttpServletResponse response, 048 byte[][] responseSoapParts, 049 Map<String, Object> context) 050 throws Exception 051 { 052 return; 053 } 054 055 public void preAction( 056 HttpServletRequest request, 057 Element[] requestSoapParts, 058 Map<String, Object> context) 059 throws Exception 060 { 061 /* 062 * This is where the magic happens. At this stage, we have 063 * the username/password known. We will delegate the authentication 064 * process down to the subclass. 065 */ 066 final String roleNames = 067 authenticate( 068 (String) context.get(XmlaConstants.CONTEXT_XMLA_USERNAME), 069 (String) context.get(XmlaConstants.CONTEXT_XMLA_PASSWORD), 070 (String) context.get(XmlaConstants.CONTEXT_XMLA_SESSION_ID)); 071 context.put( 072 XmlaConstants.CONTEXT_ROLE_NAME, 073 roleNames); 074 } 075 076 /** 077 * This function is expected to do two things. 078 * <ul> 079 * <li>Validate the credentials.</li> 080 * <li>Return a comma separated list of role names associated to 081 * these credentials.</li> 082 * </ul> 083 * <p>Should there be any problems with the credentials, subclasses 084 * can invoke {@link #throwAuthenticationException(String)} to throw 085 * an authentication exception back to the client. 086 * @param username Username used for authentication, as specified 087 * in the SOAP security header. Might be null. 088 * @param password Password used for authentication, as specified 089 * in the SOAP security header. Might be null. 090 * @param sessionID A unique identifier for this client session. 091 * Session IDs should remain the same between different queries from 092 * a same client, although some clients do not implement the XMLA 093 * Session header properly, resulting in a new session ID for each 094 * request. 095 * @return A comma separated list of roles associated to this user, 096 * or <code>null</code> for root access. 097 */ 098 public abstract String authenticate( 099 String username, 100 String password, 101 String sessionID); 102 103 /** 104 * Helper method to create and throw an authentication exception. 105 * @param reason A textual explanation of why the credentials are 106 * rejected. 107 */ 108 protected void throwAuthenticationException(String reason) { 109 throw new XmlaException( 110 XmlaConstants.CLIENT_FAULT_FC, 111 XmlaConstants.CHH_AUTHORIZATION_CODE, 112 XmlaConstants.CHH_AUTHORIZATION_FAULT_FS, 113 new Exception( 114 "There was a problem with the credentials: " 115 + reason)); 116 } 117 118 public boolean processHttpHeader( 119 HttpServletRequest request, 120 HttpServletResponse response, 121 Map<String, Object> context) 122 throws Exception 123 { 124 // We do not perform any special header treatment. 125 return true; 126 } 127} 128// End AuthenticatingXmlaRequestCallback.java