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

org.cloudfoundry.identity.uaa.client.SocialClientUserDetailsSource Maven / Gradle / Ivy

The newest version!
/*******************************************************************************
 *     Cloud Foundry 
 *     Copyright (c) [2009-2016] Pivotal Software, Inc. All Rights Reserved.
 *
 *     This product is licensed to you under the Apache License, Version 2.0 (the "License").
 *     You may not use this product except in compliance with the License.
 *
 *     This product includes a number of subcomponents with
 *     separate copyright notices and license terms. Your use of these
 *     subcomponents is subject to the terms and conditions of the
 *     subcomponent's license, as noted in the LICENSE file.
 *******************************************************************************/

package org.cloudfoundry.identity.uaa.client;

import java.util.List;
import java.util.Map;

import org.cloudfoundry.identity.uaa.client.SocialClientUserDetails.Source;
import org.cloudfoundry.identity.uaa.user.UaaAuthority;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.client.OAuth2RestTemplate;
import org.springframework.util.Assert;
import org.springframework.web.client.RestOperations;

/**
 * 

* Helper class to extract user details from a remote endpoint, triggering * authentication and approval if necessary by throwing an appropriate * exception. The exception and how it should be handled depends on the * authorization protocol in use (a RestTemplate implementation is usually * paired with a client-side filter that handles redirects to the provider). *

* *

* Tested with Facebook, Github, Cloudfoundry, Twitter, LinkedIn. Should work * with other providers if they use the same conventions in their user info * endpoint. Note that the amount of information contained in the resulting * {@link SocialClientUserDetails} depends on the provider and also on the * user's preferences with the provider (e.g. he may have chosen not to reveal * his email in github, in which case the user details will not have an email * address). *

* * @author Dave Syer * */ public class SocialClientUserDetailsSource implements InitializingBean, PreAuthenticatedPrincipalSource { private RestOperations restTemplate; private String userInfoUrl; /** * A rest template to be used to contact the remote user info endpoint. * Normally would be an instance of {@link OAuth2RestTemplate}, but there is * no need for that dependency to be explicit, and there are advantages in * making it implicit (e.g. for testing purposes). * * @param restTemplate a rest template */ public void setRestTemplate(RestOperations restTemplate) { this.restTemplate = restTemplate; } /** * The remote URL of the /userinfo endpoint or equivalent. This * should be a resource on the remote * server that provides user profile data. * * @param userInfoUrl */ public void setUserInfoUrl(String userInfoUrl) { this.userInfoUrl = userInfoUrl; } @Override public void afterPropertiesSet() { Assert.state(userInfoUrl != null, "User info URL must be provided"); Assert.state(restTemplate != null, "RestTemplate URL must be provided"); } /** * Get as much generic information as possible about the current user from * the remote endpoint. The aim is to * collect as much of the properties of a {@link SocialClientUserDetails} as * possible but not to fail if there is an * authenticated user. If one of the tested remote providers is used at * least a user id will be available, asserting * that someone has authenticated and permitted us to see some public * information. * * @return some user details */ @Override public Authentication getPrincipal() { @SuppressWarnings("unchecked") Map map = restTemplate.getForObject(userInfoUrl, Map.class); String userName = getUserName(map); String email = null; if (map.containsKey("email")) { email = map.get("email"); } if (userName == null && email != null) { userName = email; } if (userName == null) { userName = map.get("id"); // no user-friendly identifier for linked // in and google } List authorities = UaaAuthority.USER_AUTHORITIES; SocialClientUserDetails user = new SocialClientUserDetails(userName, authorities); user.setSource(Source.classify(userInfoUrl)); user.setExternalId(getUserId(map)); String fullName = getFullName(map); if (fullName != null) { user.setFullName(fullName); } if (email != null) { user.setEmail(email); } return user; } private String getFullName(Map map) { if (map.containsKey("name")) { return map.get("name"); } if (map.containsKey("formattedName")) { return map.get("formattedName"); } if (map.containsKey("fullName")) { return map.get("fullName"); } String firstName = null; if (map.containsKey("firstName")) { firstName = map.get("firstName"); } if (map.containsKey("givenName")) { firstName = map.get("givenName"); } String lastName = null; if (map.containsKey("lastName")) { lastName = map.get("lastName"); } if (map.containsKey("familyName")) { lastName = map.get("familyName"); } if (firstName != null) { if (lastName != null) { return firstName + " " + lastName; } } return null; } private Object getUserId(Map map) { String key = "id"; if (userInfoUrl.contains("run.pivotal.io")) { key = "user_id"; } return map.get(key); } private String getUserName(Map map) { String key = "username"; if (map.containsKey(key)) { return map.get(key); } if (userInfoUrl.contains("run.pivotal.io") || userInfoUrl.endsWith("/uaa/userinfo")) { key = "user_name"; } if (userInfoUrl.contains("github.com")) { key = "login"; } if (userInfoUrl.contains("twitter.com")) { key = "screen_name"; } String value = map.get(key); return value; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy