All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.yammer.backups.auth.TokenAuthInjectable Maven / Gradle / Ivy

The newest version!
package com.yammer.backups.auth;

/*
 * #%L
 * Backups
 * %%
 * Copyright (C) 2013 - 2014 Microsoft Corporation
 * %%
 * Licensed 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.
 * #L%
 */

import com.google.common.base.Optional;
import com.google.common.base.Strings;
import com.google.common.net.HttpHeaders;
import com.sun.jersey.api.core.ExtendedUriInfo;
import com.sun.jersey.api.core.HttpContext;
import com.sun.jersey.api.core.HttpRequestContext;
import com.sun.jersey.server.impl.inject.AbstractHttpContextInjectable;
import io.dropwizard.auth.AuthenticationException;
import io.dropwizard.auth.Authenticator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.ws.rs.HttpMethod;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.PathSegment;
import javax.ws.rs.core.Response;
import java.util.List;

public class TokenAuthInjectable extends AbstractHttpContextInjectable {

    private static final Logger LOG = LoggerFactory.getLogger(TokenAuthInjectable.class);
    private static final String SERVICE_PATH_SEGMENT = "service";

    private final Authenticator authenticator;
    private final boolean required;

    public TokenAuthInjectable(Authenticator authenticator, boolean required) {
        this.authenticator = authenticator;
        this.required = required;
    }

    private Optional getServiceFromPath(ExtendedUriInfo uriInfo) {
        final List segments = uriInfo.getPathSegments(SERVICE_PATH_SEGMENT);
        if (segments.isEmpty()) {
            return Optional.absent();
        }

        return Optional.fromNullable(segments.get(0).getPath());
    }

    private Optional getToken(HttpRequestContext request) {
        // Token in an Authorization header
        final String header = request.getHeaderValue(HttpHeaders.AUTHORIZATION);
        if (!Strings.isNullOrEmpty(header) && header.startsWith(TokenAuthProvider.SCHEMA)) {
            return Optional.of(header.replace(TokenAuthProvider.SCHEMA, "").trim());
        }

        // Token in URL
        final MultivaluedMap query = request.getQueryParameters();
        final Optional queryToken = Optional.fromNullable(query.getFirst("token"));
        if (queryToken.isPresent()) {
            return queryToken;
        }

        // No token provided
        return Optional.absent();
    }

    private Optional authenticateToken(String service, String token, boolean readRequest) {
        try {
            return authenticator.authenticate(new TokenCredentials(token, service, readRequest));
        }
        catch (IllegalArgumentException e) {
            LOG.debug("Error decoding credentials", e);
            throw new WebApplicationException(e, Response.Status.BAD_REQUEST);
        }
        catch (AuthenticationException e) {
            LOG.warn("Error authenticating credentials", e);
            throw new WebApplicationException(e, Response.Status.INTERNAL_SERVER_ERROR);
        }
    }

    @Override
    public T getValue(HttpContext context) {
        final Optional service = getServiceFromPath(context.getUriInfo());
        if (!service.isPresent()) {
            return null;
        }

        final Optional token = getToken(context.getRequest());
        if (token.isPresent()) {
            final String method = context.getRequest().getMethod();
            final boolean readRequest = HttpMethod.GET.equals(method);

            final Optional result = authenticateToken(service.get(), token.get(), readRequest);
            if (result.isPresent()) {
                return result.get();
            }
        }

        if (required) {
            throw new WebApplicationException(Response.status(Response.Status.UNAUTHORIZED)
                .entity("Credentials are required to access this resource.")
                .type(MediaType.TEXT_PLAIN_TYPE).build());
        }

        return null;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy