[
https://issues.apache.org/jira/browse/USERGRID-567?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14494566#comment-14494566
]
ASF GitHub Bot commented on USERGRID-567:
-----------------------------------------
Github user snoopdave commented on a diff in the pull request:
https://github.com/apache/incubator-usergrid/pull/221#discussion_r28356858
--- Diff:
stack/rest/src/main/java/org/apache/usergrid/rest/management/ManagementResource.java
---
@@ -441,6 +451,181 @@ public Viewable handleAuthorizeForm( @Context UriInfo
ui, @FormParam( "response_
}
+ /**
+ * <p>
+ * Validates access token from other or "external" Usergrid system.
+ * Calls other system's /management/me endpoint to get the User
associated with the access token.
+ * If user does not exist locally, then user and organization with the
same name of user is created.
+ * If no user is returned from the other cluster, then this endpoint
will return 401.
+ * <p>
+ *
+ * <p>
+ * See <a
href="https://issues.apache.org/jira/browse/USERGRID-567">USERGRID-567</a>
+ * for details about Usergrid Central SSO.
+ * </p>
+ *
+ * @param ui Information about calling URI.
+ * @param json JSON object with fields: ext_access_token, ttl
+ * @param callback For JSONP support.
+ * @return Returns JSON object with access_token field.
+ * @throws Exception Returns 401 if access token cannot be
validated
+ */
+ @POST
+ @Path( "/externaltoken" )
+ public Response validateExternalToken(
+ @Context UriInfo ui,
+ Map<String, Object> json,
+ @QueryParam( "callback" ) @DefaultValue( "" ) String callback
) throws Exception {
+
+ if ( StringUtils.isEmpty( properties.getProperty(
USERGRID_CENTRAL_URL ))) {
+ throw new NotImplementedException( "External Token Validation
Service is not configured" );
+ }
+
+ Object extAccessTokenObj = json.get("ext_access_token");
+ if ( extAccessTokenObj == null ) {
+ throw new IllegalArgumentException("ext_access_token must be
specified");
+ }
+ String extAccessToken = json.get("ext_access_token").toString();
+
+ Object ttlObj = json.get("ttl");
+ if ( ttlObj == null ) {
+ throw new IllegalArgumentException("ttl must be specified");
+ }
+ long ttl;
+ try {
+ ttl = Long.parseLong(ttlObj.toString());
+ } catch ( NumberFormatException e ) {
+ throw new IllegalArgumentException("ttl must be specified as a
long");
+ }
+
+ return validateExternalToken( ui, extAccessToken, ttl, callback );
+ }
+
+
+ /**
+ * <p>
+ * Validates access token from other or "external" Usergrid system.
+ * Calls other system's /management/me endpoint to get the User
associated with the access token.
+ * If user does not exist locally, then user and organization with the
same name of user is created.
+ * If no user is returned from the other cluster, then this endpoint
will return 401.
+ * </p>
+ *
+ * <p> Part of Usergrid Central SSO feature.
+ * See <a
href="https://issues.apache.org/jira/browse/USERGRID-567">USERGRID-567</a>
+ * for details about Usergrid Central SSO.
+ * </p>
+ *
+ * @param ui Information about calling URI.
+ * @param extAccessToken Access token from external Usergrid system.
+ * @param ttl Time to live for token.
+ * @param callback For JSONP support.
+ * @return Returns JSON object with access_token field.
+ * @throws Exception Returns 401 if access token cannot be
validated
+ */
+ @GET
+ @Path( "/externaltoken" )
+ public Response validateExternalToken(
+ @Context UriInfo ui,
+ @QueryParam( "ext_access_token" ) String
extAccessToken,
+ @QueryParam( "ttl" ) @DefaultValue("-1")
long ttl,
+ @QueryParam( "callback" ) @DefaultValue(
"" ) String callback )
+ throws Exception {
+
+
+ if ( StringUtils.isEmpty( properties.getProperty(
USERGRID_CENTRAL_URL ))) {
+ throw new NotImplementedException( "External Token Validation
Service is not configured" );
+ }
+
+ if ( extAccessToken == null ) {
+ throw new IllegalArgumentException("ext_access_token must be
specified");
+ }
+
+ if ( ttl == -1 ) {
+ throw new IllegalArgumentException("ttl must be specified");
+ }
+
+ // look up user via UG Central's /management/me endpoint.
+
+ JsonNode accessInfoNode = getMeFromUgCentral( extAccessToken );
+
+ JsonNode userNode = accessInfoNode.get( "user" );
+ String username = userNode.get( "username" ).getTextValue();
+ String name = userNode.get( "name" ).getTextValue();
+ String email = userNode.get( "email" ).getTextValue();
+
+ // set dummy password to random string that nobody can guess, in
SSO setup
+ // admin users should never be able to login directly to this
Usergrid system
+ String dummyPassword = RandomStringUtils.randomAlphanumeric( 40 );
+
+ // if user does not exist locally then we need to fix that
+
+ final UUID userId;
+ final OrganizationInfo organizationInfo =
management.getOrganizationByName(username);
+
+ if ( organizationInfo == null ) {
+
+ // create local user and personal organization, activate user.
+
+ OrganizationOwnerInfo ownerOrgInfo =
management.createOwnerAndOrganization(
+ username, username, name, email, dummyPassword, true,
true );
+ userId = ownerOrgInfo.getOwner().getUuid();
+
+ management.activateOrganization(
ownerOrgInfo.getOrganization() );
+
+ applicationCreator.createSampleFor(
ownerOrgInfo.getOrganization() );
+
+ } else {
+ userId = management.getAdminUserByUsername( username
).getUuid();
+ }
+
+ // store the external access_token as if it were one of our own
+ management.importTokenForAdminUser( userId, extAccessToken, ttl );
+
+ // success! return JSON object with access_token field
+ AccessInfo accessInfo = new AccessInfo()
+ .withExpiresIn(
tokens.getMaxTokenAgeInSeconds(extAccessToken ) )
+ .withAccessToken( extAccessToken );
+
+ return Response.status( SC_OK ).type( jsonMediaType( callback )
).entity( accessInfo ).build();
+ }
+
+
+ /**
+ * Look up Admin User via UG Central's /management/me endpoint.
+ *
+ * @param extAccessToken Access token issued by UG Central of Admin
User
+ * @return JsonNode representation of AccessInfo object for Admin User
+ * @throws EntityNotFoundException if access_token is not valid.
+ */
+ private JsonNode getMeFromUgCentral( String extAccessToken ) throws
EntityNotFoundException {
+
+ // create URL of central Usergrid's /management/me endpoint
+
+ String externalUrl = properties.getProperty( USERGRID_CENTRAL_URL
).trim();
+ // be lenient about trailing slash
+ externalUrl = !externalUrl.endsWith( "/" ) ? externalUrl + "/" :
externalUrl;
+ String me = externalUrl + "management/me?access_token=" +
extAccessToken;
+
+ // use our favorite HTTP client to GET /management/me
+
+ ClientConfig clientConfig = new DefaultClientConfig();
+ clientConfig.getFeatures().put(
JSONConfiguration.FEATURE_POJO_MAPPING, Boolean.TRUE);
+ Client client = Client.create(clientConfig);
+ final JsonNode accessInfoNode;
+ try {
+ accessInfoNode = client.resource( me )
+ .type( MediaType.APPLICATION_JSON_TYPE)
+ .get(JsonNode.class);
+
+ } catch ( Exception e ) {
--- End diff --
can we expose more specific error information, and throw different
exceptions, here based on what comes back from the request?
> Validate External Token for Usergrid Central SSO
> ------------------------------------------------
>
> Key: USERGRID-567
> URL: https://issues.apache.org/jira/browse/USERGRID-567
> Project: Usergrid
> Issue Type: Story
> Reporter: David Johnson
> Assignee: David Johnson
>
> The requirement is to have multiple Usergrid systems, each with its own
> Cassandra cluster, be able to authenticate Admin Users with one central
> Usergrid system -- giving Admin Users Single-Sign-On (SSO) across all of
> those systems.
> We can do this by adding just one new end-point to Usergrid.
> This Google Doc explains a complete design for "Usergrid Central SSO":
> https://docs.google.com/document/d/12kXgaYcB6L9JoTyRGn0ZHEMg3vL1LJDqvtnltIBDa1Y/edit?usp=sharing
> The design is based on earlier work by Ed Anuff and Nate McCall.
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)