com.netflix.genie.web.security.oauth2.pingfederate.PingFederateUserAuthenticationConverter.java Source code

Java tutorial

Introduction

Here is the source code for com.netflix.genie.web.security.oauth2.pingfederate.PingFederateUserAuthenticationConverter.java

Source

/*
 *
 *  Copyright 2016 Netflix, Inc.
 *
 *     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.
 *
 */
package com.netflix.genie.web.security.oauth2.pingfederate;

import com.google.common.collect.Sets;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.oauth2.common.exceptions.InvalidTokenException;
import org.springframework.security.oauth2.provider.token.DefaultUserAuthenticationConverter;

import java.util.Collection;
import java.util.Map;
import java.util.Set;

/**
 * Class to convert a map received from Ping Federate to a Spring Authentication object.
 *
 * @author tgianos
 * @since 3.0.0
 */
public class PingFederateUserAuthenticationConverter extends DefaultUserAuthenticationConverter {

    protected static final String CLIENT_ID_KEY = "client_id";
    protected static final String SCOPE_KEY = "scope";
    protected static final String GENIE_PREFIX = "genie_";
    protected static final String ROLE_PREFIX = "ROLE_";
    private static final GrantedAuthority USER_AUTHORITY = new SimpleGrantedAuthority("ROLE_USER");

    /**
     * {@inheritDoc}
     */
    //TODO: might be too much unnecessary validation in here
    @Override
    public Authentication extractAuthentication(final Map<String, ?> map) {
        // Make sure we have a client id to use as the Principle
        if (!map.containsKey(CLIENT_ID_KEY)) {
            throw new InvalidTokenException("No client id key found in map");
        }

        final Object clientIdObject = map.get(CLIENT_ID_KEY);
        if (!(clientIdObject instanceof String)) {
            throw new InvalidTokenException("Client id wasn't string");
        }

        final String userName = (String) clientIdObject;
        if (StringUtils.isBlank(userName)) {
            throw new InvalidTokenException("Client id was blank. Unable to use as user name");
        }

        // Scopes were already validated in PingFederateRemoteTokenServices
        final Object scopeObject = map.get(SCOPE_KEY);
        if (!(scopeObject instanceof Collection)) {
            throw new InvalidTokenException("Scopes were not a collection");
        }

        @SuppressWarnings("unchecked")
        final Collection<String> scopes = (Collection<String>) scopeObject;
        if (scopes.isEmpty()) {
            throw new InvalidTokenException("No scopes available. Unable to authenticate");
        }

        // Default to user role
        final Set<GrantedAuthority> authorities = Sets.newHashSet(USER_AUTHORITY);

        scopes.stream().filter(scope -> scope.contains(GENIE_PREFIX)).distinct()
                .forEach(scope -> authorities.add(new SimpleGrantedAuthority(
                        ROLE_PREFIX + StringUtils.removeStartIgnoreCase(scope, GENIE_PREFIX).toUpperCase())));

        return new UsernamePasswordAuthenticationToken(userName, "N/A", authorities);
    }
}