001/** 002 * GRANITE DATA SERVICES 003 * Copyright (C) 2006-2013 GRANITE DATA SERVICES S.A.S. 004 * 005 * This file is part of the Granite Data Services Platform. 006 * 007 * Granite Data Services 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 * Granite Data Services 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 Lesser 015 * General Public License for more details. 016 * 017 * You should have received a copy of the GNU Lesser General Public 018 * License along with this library; if not, write to the Free Software 019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 020 * USA, or see <http://www.gnu.org/licenses/>. 021 */ 022package org.granite.messaging.service.security; 023 024import java.lang.reflect.InvocationTargetException; 025import java.security.Principal; 026import java.util.Map; 027 028import javax.servlet.http.HttpServletRequest; 029import javax.servlet.http.HttpSession; 030 031import org.granite.context.GraniteContext; 032import org.granite.messaging.webapp.HttpGraniteContext; 033import org.mortbay.jetty.HttpConnection; 034import org.mortbay.jetty.Request; 035import org.mortbay.jetty.security.UserRealm; 036 037/** 038 * @author William DRAI 039 */ 040public class Jetty6SecurityService extends AbstractSecurityService { 041 042 private static final String JETTY6_AUTH = "org.granite.messaging.service.security.Jetty6Auth"; 043 044 045 public Jetty6SecurityService() { 046 super(); 047 } 048 049 050 public void configure(Map<String, String> params) { 051 } 052 053 054 public void login(Object credentials, String charset) throws SecurityServiceException { 055 String[] decoded = decodeBase64Credentials(credentials, charset); 056 057 HttpGraniteContext graniteContext = (HttpGraniteContext)GraniteContext.getCurrentInstance(); 058 HttpServletRequest httpRequest = graniteContext.getRequest(); 059 Request request = httpRequest instanceof Request ? (Request)httpRequest : HttpConnection.getCurrentConnection().getRequest(); 060 UserRealm realm = request.getUserRealm(); 061 062 Principal principal = realm.authenticate(decoded[0], decoded[1], request); 063 if (principal == null) { 064 if (request.getSession(false) != null) 065 request.getSession(false).removeAttribute(JETTY6_AUTH); 066 throw SecurityServiceException.newInvalidCredentialsException("Wrong username or password"); 067 } 068 069 request.setAuthType(AUTH_TYPE); 070 request.setUserPrincipal(principal); 071 072 request.getSession().setAttribute(JETTY6_AUTH, principal); 073 074 endLogin(credentials, charset); 075 } 076 077 078 public Object authorize(AbstractSecurityContext context) throws Exception { 079 080 startAuthorization(context); 081 082 HttpGraniteContext graniteContext = (HttpGraniteContext)GraniteContext.getCurrentInstance(); 083 HttpServletRequest httpRequest = graniteContext.getRequest(); 084 085 boolean reauth = false; 086 Principal principal = httpRequest.getUserPrincipal(); 087 if (principal == null) { 088 HttpSession session = httpRequest.getSession(false); 089 principal = session != null ? (Principal)session.getAttribute(JETTY6_AUTH) : null; 090 reauth = true; 091 } 092 093 if (principal == null && tryRelogin()) { 094 principal = httpRequest.getUserPrincipal(); 095 reauth = false; 096 } 097 098 if (principal == null) { 099 if (httpRequest.getRequestedSessionId() != null) { 100 HttpSession httpSession = httpRequest.getSession(false); 101 if (httpSession == null || httpRequest.getRequestedSessionId().equals(httpSession.getId())) 102 throw SecurityServiceException.newSessionExpiredException("Session expired"); 103 } 104 throw SecurityServiceException.newNotLoggedInException("User not logged in"); 105 } 106 107 Request request = httpRequest instanceof Request ? (Request)httpRequest : HttpConnection.getCurrentConnection().getRequest(); 108 UserRealm realm = request.getUserRealm(); 109 if (reauth) 110 realm.reauthenticate(principal); 111 112 // Check destination access 113 if (context.getDestination().isSecured()) { 114 boolean accessDenied = true; 115 for (String role : context.getDestination().getRoles()) { 116 if (realm.isUserInRole(principal, role)) { 117 accessDenied = false; 118 break; 119 } 120 } 121 if (accessDenied) 122 throw SecurityServiceException.newAccessDeniedException("User not in required role"); 123 124 request.setAuthType(AUTH_TYPE); 125 request.setUserPrincipal(principal); 126 } 127 128 try { 129 return endAuthorization(context); 130 } catch (InvocationTargetException e) { 131 for (Throwable t = e; t != null; t = t.getCause()) { 132 if (t instanceof SecurityException) 133 throw SecurityServiceException.newAccessDeniedException(t.getMessage()); 134 } 135 throw e; 136 } 137 } 138 139 140 public void logout() throws SecurityServiceException { 141 HttpGraniteContext graniteContext = (HttpGraniteContext)GraniteContext.getCurrentInstance(); 142 HttpServletRequest httpRequest = graniteContext.getRequest(); 143 Request request = httpRequest instanceof Request ? (Request)httpRequest : HttpConnection.getCurrentConnection().getRequest(); 144 UserRealm realm = request.getUserRealm(); 145 146 realm.disassociate(httpRequest.getUserPrincipal()); 147 148 endLogout(); 149 } 150}