/* * $Id: WebServiceAuthorizationFilter.java,v 1.2 2007/01/22 08:16:56 tryggvil Exp $ * Created on Apr 4, 2006 * * Copyright (C) 2006 Idega Software hf. All Rights Reserved. * * This software is the proprietary information of Idega hf. * Use is subject to license terms. */ package com.idega.servlet.filter; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.charset.Charset; import java.util.Iterator; import java.util.List; import javax.ejb.FinderException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.codec.binary.Base64; import com.idega.business.IBORuntimeException; import com.idega.core.accesscontrol.business.AccessController; import com.idega.core.accesscontrol.business.LoginBusinessBean; import com.idega.core.accesscontrol.data.LoginTable; import com.idega.core.accesscontrol.data.LoginTableHome; import com.idega.data.IDOLookup; import com.idega.data.IDOLookupException; import com.idega.idegaweb.IWApplicationContext; import com.idega.idegaweb.IWMainApplication; import com.idega.user.business.UserBusiness; import com.idega.user.data.Group; import com.idega.user.data.User; import com.idega.util.StringHandler; /** * <p> * This Servlet filter sits by default in front of all (Axis) web services and * blocks unpriviliged access. <br/> * So access by clients that desire to use the services needs to be configured * with the WS_DO_BASIC_AUTHENTICATION or WS_VALID_IP application properties. * </p> * Last modified: $Date: 2007/01/22 08:16:56 $ by $Author: tryggvil $ * * @author <a href="mailto:thomas@idega.com">thomas</a> * @version $Revision: 1.2 $ */ public class WebServiceAuthorizationFilter implements Filter { public static final String WS_ALLOW_ALL_IPS = "*"; private final String WEB_SERVICE_USER_ROLE = "web_service_user"; private final String DO_BASIC_AUTHENTICATION = "WS_DO_BASIC_AUTHENTICATION"; private final String VALID_IP = "WS_VALID_IP"; LoginBusinessBean loginBusiness = null; LoginTableHome loginTableHome = null; UserBusiness userBusiness = null; /* * (non-Javadoc) * * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, * javax.servlet.ServletResponse, javax.servlet.FilterChain) */ @Override public void doFilter(ServletRequest myRequest, ServletResponse myResponse, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) myRequest; HttpServletResponse response = (HttpServletResponse) myResponse; ServletContext myServletContext = request.getSession() .getServletContext(); // getting the application context IWMainApplication mainApplication = IWMainApplication .getIWMainApplication(myServletContext); boolean doCheck = mainApplication.getIWApplicationContext() .getApplicationSettings().getBoolean( this.DO_BASIC_AUTHENTICATION, true); if (doCheck) { if (!requestIsValid(request)) { // send a 403 error response.sendError(HttpServletResponse.SC_FORBIDDEN); return; } } else { boolean isValid = false; try { String validIP = mainApplication.getIWApplicationContext() .getApplicationSettings() .getProperty(this.VALID_IP, ""); if (WS_ALLOW_ALL_IPS.equals(validIP)) { isValid = true; } else { String[] ips = validIP.split("\\;"); for (int i = 0; i < ips.length; i++) { if (ips[i].equals(request.getRemoteAddr())) { isValid = true; break; } } } } catch (Exception e) { isValid = false; } if (!isValid) { // send a 403 error response.sendError(HttpServletResponse.SC_FORBIDDEN); return; } } chain.doFilter(request, response); } private boolean requestIsValid(HttpServletRequest request) { String decodedNamePassword = getDecodedNamePassword(request); if (decodedNamePassword == null) { return false; } int delimiterIndex = decodedNamePassword.indexOf(":"); if (delimiterIndex < 0) { return false; } String name = decodedNamePassword.substring(0, delimiterIndex); String password = decodedNamePassword.substring(delimiterIndex + 1); if (!StringHandler.isNotEmpty(name)) { return false; } if (!StringHandler.isNotEmpty(password)) { return false; } return checkUserPasswordAndRole(request, name, password); } private boolean checkUserPasswordAndRole(HttpServletRequest myRequest, String name, String password) { // The following code does not work, therefore we are using the own test // method // if (myRequest.isUserInRole(WEB_SERVICE_USER_ROLE)) { // System.out.println("user is in role"); // } ServletContext myServletContext = myRequest.getSession() .getServletContext(); // getting the application context IWMainApplication mainApplication = IWMainApplication .getIWMainApplication(myServletContext); IWApplicationContext iwac = mainApplication.getIWApplicationContext(); try { LoginTable loginTable = getLoginTableHome().findByLogin(name); if (!hasRole(loginTable, mainApplication)) { return false; } return getLoginBusiness(iwac).verifyPassword(loginTable, password); } catch (FinderException ex) { return false; } } private boolean hasRole(LoginTable loginTable, IWMainApplication iwMainApplication) { User user = loginTable.getUser(); List groups = user.getParentGroups(); Iterator groupIterator = groups.iterator(); AccessController accessController = iwMainApplication .getAccessController(); while (groupIterator.hasNext()) { Group group = (Group) groupIterator.next(); if (accessController.hasRole(this.WEB_SERVICE_USER_ROLE, group, null)) { return true; } } return false; } private String getDecodedNamePassword(HttpServletRequest request) { String basicNamePassword = request.getHeader("Authorization"); if (basicNamePassword == null) { return null; } basicNamePassword = basicNamePassword.trim(); if (!basicNamePassword.startsWith("Basic")) { return null; } if (basicNamePassword.length() < 6) { return null; } String namePassword = basicNamePassword.substring(6); try { byte[] decodedNamePasswordArray = Base64.decodeBase64(namePassword.getBytes()); ByteBuffer wrappedDecodedNamePasswordArray = ByteBuffer.wrap(decodedNamePasswordArray); Charset charset = Charset.forName("ISO-8859-1"); CharBuffer buffer = charset.decode(wrappedDecodedNamePasswordArray); return buffer.toString(); } catch (Exception ex) { return null; } } private LoginBusinessBean getLoginBusiness(IWApplicationContext iwac) { if (this.loginBusiness == null) { this.loginBusiness = LoginBusinessBean.getLoginBusinessBean(iwac); } return this.loginBusiness; } private LoginTableHome getLoginTableHome() { if (this.loginTableHome == null) { try { this.loginTableHome = (LoginTableHome) IDOLookup .getHome(LoginTable.class); } catch (IDOLookupException ile) { throw new IBORuntimeException(ile); } } return this.loginTableHome; } @Override public void destroy() { // noting to destroy } @Override public void init(FilterConfig filterConfig) throws ServletException { } }