Skip to content

Commit

Permalink
Fix login for external oidc provider when idp discovery is turned on
Browse files Browse the repository at this point in the history
[#117269923] https://www.pivotaltracker.com/story/show/117269923

Signed-off-by: Madhura Bhave <mbhave@pivotal.io>
  • Loading branch information
mbhave committed May 13, 2016
1 parent 9235414 commit 33e00b6
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 9 deletions.
Expand Up @@ -49,6 +49,7 @@
import org.springframework.security.web.savedrequest.SavedRequest;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
Expand Down Expand Up @@ -364,7 +365,7 @@ private String redirectToExternalProvider(AbstractIdentityProviderDefinition idp
if(idpForRedirect != null) {
if (idpForRedirect instanceof SamlIdentityProviderDefinition) {
String url = SamlRedirectUtils.getIdpRedirectUrl((SamlIdentityProviderDefinition) idpForRedirect, entityID);
return "redirect:" + url;
return "redirect:/" + url;
} else if (idpForRedirect instanceof AbstractXOAuthIdentityProviderDefinition) {
try {
String redirectUrl = getRedirectUrlForXOAuthIDP(request, alias, (AbstractXOAuthIdentityProviderDefinition) idpForRedirect);
Expand All @@ -383,8 +384,10 @@ private String getRedirectUrlForXOAuthIDP(HttpServletRequest request, String ali
List<String> query = new ArrayList<>();
query.add("client_id=" + definition.getRelyingPartyId());
query.add("response_type=code");
query.add("redirect_uri=" + URLEncoder.encode(request.getRequestURL() + "/callback/" + alias, "UTF-8"));
if(definition.getScopes() != null && !definition.getScopes().isEmpty()) query.add("scope=" + URLEncoder.encode(String.join(" ", definition.getScopes()), "UTF-8"));
String requestURL = request.getRequestURL().toString();
String rootContext = StringUtils.hasText(request.getServletPath()) ? requestURL.substring(0, requestURL.indexOf(request.getServletPath())) : requestURL;
query.add("redirect_uri=" + URLEncoder.encode(rootContext + "/login/callback/" + alias, "UTF-8"));
if (definition.getScopes() != null && !definition.getScopes().isEmpty()) query.add("scope=" + URLEncoder.encode(String.join(" ", definition.getScopes()), "UTF-8"));
String queryString = String.join("&", query);

return authUrlBase + queryAppendDelimiter + queryString;
Expand All @@ -395,7 +398,6 @@ protected Map<String, SamlIdentityProviderDefinition> getSamlIdentityProviderDef
return filteredIdps.stream().collect(new MapCollector<>(SamlIdentityProviderDefinition::getUniqueAlias, idp -> idp));
}


protected Map<String, AbstractXOAuthIdentityProviderDefinition> getOauthIdentityProviderDefinitions(List<String> allowedIdps) {
final List<String> types = Arrays.asList(OAUTH20, OIDC10);
List<IdentityProvider> identityProviders = providerProvisioning.retrieveAll(true, IdentityZoneHolder.get().getId());
Expand Down
Expand Up @@ -20,6 +20,7 @@
import org.cloudfoundry.identity.uaa.mock.util.MockMvcUtils.IdentityZoneCreationResult;
import org.cloudfoundry.identity.uaa.oauth.client.ClientConstants;
import org.cloudfoundry.identity.uaa.provider.AbstractIdentityProviderDefinition;
import org.cloudfoundry.identity.uaa.provider.AbstractXOAuthIdentityProviderDefinition;
import org.cloudfoundry.identity.uaa.provider.IdentityProvider;
import org.cloudfoundry.identity.uaa.provider.IdentityProviderProvisioning;
import org.cloudfoundry.identity.uaa.provider.LdapIdentityProviderDefinition;
Expand Down Expand Up @@ -925,7 +926,7 @@ public String[] getParameterValues(String name) {
.session(session)
.with(new SetServerNameRequestPostProcessor(identityZone.getSubdomain() + ".localhost")))
.andExpect(status().isFound())
.andExpect(redirectedUrl("saml/discovery?returnIDParam=idp&entityID=" + identityZone.getSubdomain() + ".cloudfoundry-saml-login&idp=" + alias + "&isPassive=true"));
.andExpect(redirectedUrl("/saml/discovery?returnIDParam=idp&entityID=" + identityZone.getSubdomain() + ".cloudfoundry-saml-login&idp=" + alias + "&isPassive=true"));

getMockMvc().perform(get("/login")
.accept(APPLICATION_JSON)
Expand Down Expand Up @@ -988,9 +989,8 @@ public void samlRedirect_onlyOneProvider_noClientContext() throws Exception {
getMockMvc().perform(get("/login").accept(TEXT_HTML).with(new SetServerNameRequestPostProcessor(identityZone.getSubdomain() + ".localhost"))
.with(new SetServerNameRequestPostProcessor(identityZone.getSubdomain() + ".localhost")))
.andExpect(status().isFound())
.andExpect(redirectedUrl("saml/discovery?returnIDParam=idp&entityID=" + identityZone.getSubdomain() + ".cloudfoundry-saml-login&idp="+alias+"&isPassive=true"));
.andExpect(redirectedUrl("/saml/discovery?returnIDParam=idp&entityID=" + identityZone.getSubdomain() + ".cloudfoundry-saml-login&idp="+alias+"&isPassive=true"));
IdentityZoneHolder.clear();

}

@Test
Expand Down Expand Up @@ -1027,6 +1027,7 @@ public void xOAuthRedirect_onlyOneProvider_noClientContext() throws Exception {
identityProviderProvisioning.update(uaaIdentityProvider);

getMockMvc().perform(get("/login").accept(TEXT_HTML)
.servletPath("/login")
.with(new SetServerNameRequestPostProcessor(identityZone.getSubdomain() + ".localhost")))
.andExpect(status().isFound())
.andExpect(redirectedUrl("http://auth.url?client_id=uaa&response_type=code&redirect_uri=http%3A%2F%2F" + identityZone.getSubdomain() + ".localhost%2Flogin%2Fcallback%2F" + oauthAlias + "&scope=openid+roles"));
Expand Down Expand Up @@ -1073,6 +1074,7 @@ public void testLoginHintRedirect() throws Exception {
getMockMvc().perform(get("/login")
.accept(TEXT_HTML)
.session(session)
.servletPath("/login")
.with(new SetServerNameRequestPostProcessor(identityZone.getSubdomain() + ".localhost"))
)
.andExpect(status().isFound())
Expand Down Expand Up @@ -1738,7 +1740,7 @@ public void emailPageIdpDiscoveryEnabled_SelfServiceLinksDisabled() throws Excep
}

@Test
public void idpDiscoveryRedirectsToMatchedExternalProvider_withClientContext() throws Exception {
public void idpDiscoveryRedirectsToSamlExternalProvider_withClientContext() throws Exception {
IdentityZone zone = MultitenancyFixture.identityZone("test-saml", "test-saml");
createOtherIdentityZone(zone.getSubdomain(), getMockMvc(), getWebApplicationContext());

Expand All @@ -1750,7 +1752,35 @@ public void idpDiscoveryRedirectsToMatchedExternalProvider_withClientContext() t
.session(session)
.param("email", "marissa@test.org")
.with(new SetServerNameRequestPostProcessor(zone.getSubdomain() + ".localhost")))
.andExpect(redirectedUrl("saml/discovery?returnIDParam=idp&entityID="+ zone.getSubdomain() + ".cloudfoundry-saml-login&idp=" + originKey + "&isPassive=true"));
.andExpect(redirectedUrl("/saml/discovery?returnIDParam=idp&entityID=" + zone.getSubdomain() + ".cloudfoundry-saml-login&idp=" + originKey + "&isPassive=true"));
}

@Test
public void idpDiscoveryRedirectsToOIDCProvider() throws Exception {
IdentityZone zone = MultitenancyFixture.identityZone("oidc-idp-discovery", "oidc-idp-discovery");
createOtherIdentityZone(zone.getSubdomain(), getMockMvc(), getWebApplicationContext());

String originKey = generator.generate();
AbstractXOAuthIdentityProviderDefinition definition = new XOIDCIdentityProviderDefinition();
definition.setEmailDomain(Arrays.asList("test.org"));
definition.setAuthUrl(new URL("http://myauthurl.com"));
definition.setTokenKey("key");
definition.setTokenUrl(new URL("http://mytokenurl.com"));
definition.setRelyingPartyId("id");
definition.setRelyingPartySecret("secret");
definition.setLinkText("my oidc provider");

IdentityProvider identityProvider = MultitenancyFixture.identityProvider(originKey, zone.getId());
identityProvider.setType(OriginKeys.OIDC10);
identityProvider.setConfig(definition);
MockMvcUtils.createIdpUsingWebRequest(getMockMvc(), zone.getId(), adminToken, identityProvider, status().isCreated());

getMockMvc().perform(post("/login/idp_discovery")
.header("Accept", TEXT_HTML)
.servletPath("/login/idp_discovery")
.param("email", "marissa@test.org")
.with(new SetServerNameRequestPostProcessor(zone.getSubdomain() + ".localhost")))
.andExpect(redirectedUrl("http://myauthurl.com?client_id=id&response_type=code&redirect_uri=http%3A%2F%2Foidc-idp-discovery.localhost%2Flogin%2Fcallback%2F" +originKey));
}

@Test
Expand Down

0 comments on commit 33e00b6

Please sign in to comment.