001    /*
002      GRANITE DATA SERVICES
003      Copyright (C) 2011 GRANITE DATA SERVICES S.A.S.
004    
005      This file is part of Granite Data Services.
006    
007      Granite Data Services is free software; you can redistribute it and/or modify
008      it under the terms of the GNU Library General Public License as published by
009      the Free Software Foundation; either version 2 of the License, or (at your
010      option) any later version.
011    
012      Granite Data Services is distributed in the hope that it will be useful, but
013      WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
014      FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License
015      for more details.
016    
017      You should have received a copy of the GNU Library General Public License
018      along with this library; if not, see <http://www.gnu.org/licenses/>.
019    */
020    
021    package org.granite.messaging.service.security;
022    
023    import java.lang.reflect.InvocationTargetException;
024    import java.security.Principal;
025    import java.util.Map;
026    
027    import javax.security.auth.login.LoginException;
028    import javax.servlet.http.HttpServletRequest;
029    import javax.servlet.http.HttpServletResponse;
030    import javax.servlet.http.HttpSession;
031    
032    import org.granite.context.GraniteContext;
033    import org.granite.messaging.webapp.HttpGraniteContext;
034    
035    import weblogic.servlet.security.ServletAuthentication;
036    
037    /**
038     * @author Franck WOLFF
039     */
040    public class WebLogicSecurityService extends AbstractSecurityService {
041    
042        public WebLogicSecurityService() {
043        }
044    
045        public void configure(Map<String, String> params) {
046        }
047    
048        public void login(Object credentials) throws SecurityServiceException {
049            String[] decoded = decodeBase64Credentials(credentials);
050    
051            HttpGraniteContext context = (HttpGraniteContext)GraniteContext.getCurrentInstance();
052            HttpServletRequest httpRequest = context.getRequest();
053            HttpServletResponse httpResponse = context.getResponse();
054    
055            int result = ServletAuthentication.FAILED_AUTHENTICATION;
056            try {
057                    result = ServletAuthentication.login(decoded[0], decoded[1], httpRequest, httpResponse);
058            }
059            catch (LoginException e) {
060            }
061            if (result != ServletAuthentication.AUTHENTICATED)
062                    throw SecurityServiceException.newInvalidCredentialsException("Wrong username or password");
063            
064            // Make sure we have a valid HTTP session.
065            httpRequest.getSession(true);
066            
067            endLogin(credentials);
068        }
069    
070        public Object authorize(AbstractSecurityContext context) throws Exception {
071    
072            startAuthorization(context);
073    
074            if (context.getDestination().isSecured()) {
075                HttpGraniteContext graniteContext = (HttpGraniteContext)GraniteContext.getCurrentInstance();
076                HttpServletRequest httpRequest = graniteContext.getRequest();
077    
078                Principal principal = httpRequest.getUserPrincipal();
079                if (principal == null && tryRelogin())
080                    principal = httpRequest.getUserPrincipal();
081                
082                if (principal == null) {
083                    if (httpRequest.getRequestedSessionId() != null) {
084                        HttpSession httpSession = httpRequest.getSession(false);
085                        if (httpSession == null || httpRequest.getRequestedSessionId().equals(httpSession.getId()))
086                            throw SecurityServiceException.newSessionExpiredException("Session expired");
087                    }
088                    throw SecurityServiceException.newNotLoggedInException("User not logged in");
089                }
090                
091                boolean accessDenied = true;
092                for (String role : context.getDestination().getRoles()) {
093                    if (httpRequest.isUserInRole(role)) {
094                        accessDenied = false;
095                        break;
096                    }
097                }
098                if (accessDenied)
099                    throw SecurityServiceException.newAccessDeniedException("User not in required role");
100            }
101    
102            try {
103                return endAuthorization(context);
104            } catch (InvocationTargetException e) {
105                for (Throwable t = e; t != null; t = t.getCause()) {
106                    // Don't create a dependency to javax.ejb in SecurityService...
107                    if (t instanceof SecurityException ||
108                        "javax.ejb.EJBAccessException".equals(t.getClass().getName()))
109                        throw SecurityServiceException.newAccessDeniedException(t.getMessage());
110                }
111                throw e;
112            }
113        }
114    
115        public void logout() throws SecurityServiceException {
116            HttpGraniteContext graniteContext = (HttpGraniteContext)GraniteContext.getCurrentInstance();
117            HttpServletRequest httpRequest = graniteContext.getRequest();
118    
119            endLogout();
120            
121            // Make sure we invalidate current HTTP session.
122            if (httpRequest.getSession(false) != null)
123                    httpRequest.getSession().invalidate();
124    
125            ServletAuthentication.logout(httpRequest);
126        }
127    }