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 */
022 package org.granite.messaging.service.security;
023
024 import java.lang.reflect.InvocationTargetException;
025 import java.security.Principal;
026 import java.util.Map;
027
028 import javax.servlet.http.HttpServletRequest;
029 import javax.servlet.http.HttpSession;
030
031 import org.granite.context.GraniteContext;
032 import org.granite.messaging.webapp.HttpGraniteContext;
033 import org.mortbay.jetty.HttpConnection;
034 import org.mortbay.jetty.Request;
035 import org.mortbay.jetty.security.UserRealm;
036
037 /**
038 * @author William DRAI
039 */
040 public 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 }