/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.sling.extensions.webconsolesecurityprovider.internal; import java.util.Iterator; import javax.jcr.RepositoryException; import javax.jcr.Session; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.felix.webconsole.WebConsoleSecurityProvider3; import org.apache.jackrabbit.api.JackrabbitSession; import org.apache.jackrabbit.api.security.user.Authorizable; import org.apache.jackrabbit.api.security.user.Group; import org.apache.jackrabbit.api.security.user.User; import org.apache.jackrabbit.api.security.user.UserManager; import org.apache.sling.api.auth.Authenticator; import org.apache.sling.api.resource.ResourceResolver; import org.apache.sling.auth.core.AuthenticationSupport; /** * The <code>SlingWebConsoleSecurityProvider</code> is security provider for the * Apache Felix Web Console which validates the user name and password by loging * into the repository and the checking whether the user is allowed access. * Access granted by the {@link #authenticate(String, String)} method applies to * all of the Web Console since the {@link #authorize(Object, String)} method * always returns <code>true</code>. * <p> * This security provider requires a JCR Repository to operate. Therefore it is * only registered as a security provider service once such a JCR Repository is * available. */ public class SlingWebConsoleSecurityProvider2 extends AbstractWebConsoleSecurityProvider implements WebConsoleSecurityProvider3 { private final AuthenticationSupport authentiationSupport; private final Authenticator authenticator; public SlingWebConsoleSecurityProvider2(final Object support, final Object authenticator) { this.authentiationSupport = (AuthenticationSupport)support; this.authenticator = (Authenticator)authenticator; } /** * @see org.apache.felix.webconsole.WebConsoleSecurityProvider2#authenticate(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) */ @Override public boolean authenticate(final HttpServletRequest request, final HttpServletResponse response) { if ( this.authentiationSupport.handleSecurity(request, response) ) { // get ResourceResolver (set by AuthenticationSupport) Object resolverObject = request.getAttribute(AuthenticationSupport.REQUEST_ATTRIBUTE_RESOLVER); final ResourceResolver resolver = (resolverObject instanceof ResourceResolver) ? (ResourceResolver) resolverObject : null; if ( resolver != null ) { final Session session = resolver.adaptTo(Session.class); if ( session != null ) { try { final User u = this.authenticate(session); if ( u != null ) { request.setAttribute(USER_ATTRIBUTE, u); return true; } } catch (final Exception re) { logger.info("authenticate: Generic problem trying grant User " + " access to the Web Console", re); } } } if (request.getAuthType() == null) { this.authenticator.login(request, response); } } return false; } @Override public void logout(HttpServletRequest request, HttpServletResponse response) { this.authenticator.logout(request, response); } @Override public User authenticate(String userName, String password) { return null; // this method is never invoked } private User authenticate(final Session session) throws RepositoryException { String userId = session.getUserID(); if (session instanceof JackrabbitSession) { UserManager umgr = ((JackrabbitSession) session).getUserManager(); Authorizable a = umgr.getAuthorizable(userId); if (a instanceof User) { // check users if (users.contains(userId)) { return (User)a; } // check groups Iterator<Group> gi = a.memberOf(); while (gi.hasNext()) { if (groups.contains(gi.next().getID())) { return (User)a; } } logger.info( "authenticate: User {} is denied Web Console access", userId); } else { logger.error( "authenticate: Expected user ID {} to refer to a user", userId); } } else { logger.info( "authenticate: Jackrabbit Session required to grant access to the Web Console for {}; got {}", userId, session.getClass()); } return null; } /** * All users authenticated with the repository and being a member of the * authorized groups are granted access for all roles in the Web Console. */ @Override public boolean authorize(Object user, String role) { logger.debug("authorize: Grant user {} access for role {}", user, role); return true; } }