added login hint capability to client library

pull/820/merge
Justin Richer 2015-06-23 21:21:41 -04:00
parent f7a082d4b8
commit c166cbe49c
8 changed files with 92 additions and 10 deletions

View File

@ -262,7 +262,7 @@ public class OIDCAuthenticationFilter extends AbstractAuthenticationProcessingFi
Map<String, String> options = authOptions.getOptions(serverConfig, clientConfig, request);
String authRequest = authRequestBuilder.buildAuthRequestUrl(serverConfig, clientConfig, redirectUri, nonce, state, options);
String authRequest = authRequestBuilder.buildAuthRequestUrl(serverConfig, clientConfig, redirectUri, nonce, state, options, issResp.getLoginHint());
logger.debug("Auth Request: " + authRequest);

View File

@ -25,6 +25,8 @@ import org.mitre.oauth2.model.RegisteredClient;
import org.mitre.openid.connect.config.ServerConfiguration;
/**
* Builds a URL string to the IdP's authorization endpoint.
*
* @author jricher
*
*/
@ -36,8 +38,9 @@ public interface AuthRequestUrlBuilder {
* @param redirectUri
* @param nonce
* @param state
* @param loginHint
* @return
*/
public String buildAuthRequestUrl(ServerConfiguration serverConfig, RegisteredClient clientConfig, String redirectUri, String nonce, String state, Map<String, String> options);
public String buildAuthRequestUrl(ServerConfiguration serverConfig, RegisteredClient clientConfig, String redirectUri, String nonce, String state, Map<String, String> options, String loginHint);
}

View File

@ -32,6 +32,7 @@ import org.mitre.openid.connect.config.ServerConfiguration;
import org.springframework.security.authentication.AuthenticationServiceException;
import com.google.common.base.Joiner;
import com.google.common.base.Strings;
import com.nimbusds.jose.EncryptionMethod;
import com.nimbusds.jose.JWEAlgorithm;
import com.nimbusds.jose.JWEHeader;
@ -54,7 +55,7 @@ public class EncryptedAuthRequestUrlBuilder implements AuthRequestUrlBuilder {
* @see org.mitre.openid.connect.client.service.AuthRequestUrlBuilder#buildAuthRequestUrl(org.mitre.openid.connect.config.ServerConfiguration, org.mitre.oauth2.model.RegisteredClient, java.lang.String, java.lang.String, java.lang.String, java.util.Map)
*/
@Override
public String buildAuthRequestUrl(ServerConfiguration serverConfig, RegisteredClient clientConfig, String redirectUri, String nonce, String state, Map<String, String> options) {
public String buildAuthRequestUrl(ServerConfiguration serverConfig, RegisteredClient clientConfig, String redirectUri, String nonce, String state, Map<String, String> options, String loginHint) {
// create our signed JWT for the request object
JWTClaimsSet claims = new JWTClaimsSet();
@ -77,6 +78,11 @@ public class EncryptedAuthRequestUrlBuilder implements AuthRequestUrlBuilder {
for (Entry<String, String> option : options.entrySet()) {
claims.setClaim(option.getKey(), option.getValue());
}
// if there's a login hint, send it
if (!Strings.isNullOrEmpty(loginHint)) {
claims.setClaim("login_hint", loginHint);
}
EncryptedJWT jwt = new EncryptedJWT(new JWEHeader(alg, enc), claims);

View File

@ -30,6 +30,7 @@ import org.mitre.openid.connect.config.ServerConfiguration;
import org.springframework.security.authentication.AuthenticationServiceException;
import com.google.common.base.Joiner;
import com.google.common.base.Strings;
/**
*
@ -44,7 +45,7 @@ public class PlainAuthRequestUrlBuilder implements AuthRequestUrlBuilder {
* @see org.mitre.openid.connect.client.service.AuthRequestUrlBuilder#buildAuthRequest(javax.servlet.http.HttpServletRequest, org.mitre.openid.connect.config.ServerConfiguration, org.springframework.security.oauth2.provider.ClientDetails)
*/
@Override
public String buildAuthRequestUrl(ServerConfiguration serverConfig, RegisteredClient clientConfig, String redirectUri, String nonce, String state, Map<String, String> options) {
public String buildAuthRequestUrl(ServerConfiguration serverConfig, RegisteredClient clientConfig, String redirectUri, String nonce, String state, Map<String, String> options, String loginHint) {
try {
URIBuilder uriBuilder = new URIBuilder(serverConfig.getAuthorizationEndpointUri());
@ -62,6 +63,11 @@ public class PlainAuthRequestUrlBuilder implements AuthRequestUrlBuilder {
for (Entry<String, String> option : options.entrySet()) {
uriBuilder.addParameter(option.getKey(), option.getValue());
}
// if there's a login hint, send it
if (!Strings.isNullOrEmpty(loginHint)) {
uriBuilder.addParameter("login_hint", loginHint);
}
return uriBuilder.build().toString();

View File

@ -31,6 +31,7 @@ import org.mitre.openid.connect.config.ServerConfiguration;
import org.springframework.security.authentication.AuthenticationServiceException;
import com.google.common.base.Joiner;
import com.google.common.base.Strings;
import com.nimbusds.jose.JWSAlgorithm;
import com.nimbusds.jose.JWSHeader;
import com.nimbusds.jwt.JWTClaimsSet;
@ -48,7 +49,7 @@ public class SignedAuthRequestUrlBuilder implements AuthRequestUrlBuilder {
* @see org.mitre.openid.connect.client.service.AuthRequestUrlBuilder#buildAuthRequestUrl(org.mitre.openid.connect.config.ServerConfiguration, org.springframework.security.oauth2.provider.ClientDetails, java.lang.String, java.lang.String, java.lang.String)
*/
@Override
public String buildAuthRequestUrl(ServerConfiguration serverConfig, RegisteredClient clientConfig, String redirectUri, String nonce, String state, Map<String, String> options) {
public String buildAuthRequestUrl(ServerConfiguration serverConfig, RegisteredClient clientConfig, String redirectUri, String nonce, String state, Map<String, String> options, String loginHint) {
// create our signed JWT for the request object
JWTClaimsSet claims = new JWTClaimsSet();
@ -71,6 +72,11 @@ public class SignedAuthRequestUrlBuilder implements AuthRequestUrlBuilder {
for (Entry<String, String> option : options.entrySet()) {
claims.setClaim(option.getKey(), option.getValue());
}
// if there's a login hint, send it
if (!Strings.isNullOrEmpty(loginHint)) {
claims.setClaim("login_hint", loginHint);
}
JWSAlgorithm alg = clientConfig.getRequestObjectSigningAlg();
if (alg == null) {

View File

@ -98,7 +98,7 @@ public class WebfingerIssuerService implements IssuerService {
throw new AuthenticationServiceException("Issuer was in blacklist: " + issuer);
}
return new IssuerServiceResponse(issuer, null, null);
return new IssuerServiceResponse(issuer, identifier, null);
} catch (UncheckedExecutionException ue) {
logger.warn("Issue fetching issuer for user input: " + identifier, ue);
return null;

View File

@ -69,7 +69,27 @@ public class TestPlainAuthRequestUrlBuilder {
Map<String, String> options = ImmutableMap.of("foo", "bar");
String actualUrl = urlBuilder.buildAuthRequestUrl(serverConfig, clientConfig, "https://client.example.org/", "34fasf3ds", "af0ifjsldkj", options);
String actualUrl = urlBuilder.buildAuthRequestUrl(serverConfig, clientConfig, "https://client.example.org/", "34fasf3ds", "af0ifjsldkj", options, null);
assertThat(actualUrl, equalTo(expectedUrl));
}
@Test
public void buildAuthRequestUrl_withLoginHint() {
String expectedUrl = "https://server.example.com/authorize?" +
"response_type=code" +
"&client_id=s6BhdRkqt3" +
"&scope=openid+profile" + // plus sign used for space per application/x-www-form-encoded standard
"&redirect_uri=https%3A%2F%2Fclient.example.org%2F" +
"&nonce=34fasf3ds" +
"&state=af0ifjsldkj" +
"&foo=bar" +
"&login_hint=bob";
Map<String, String> options = ImmutableMap.of("foo", "bar");
String actualUrl = urlBuilder.buildAuthRequestUrl(serverConfig, clientConfig, "https://client.example.org/", "34fasf3ds", "af0ifjsldkj", options, "bob");
assertThat(actualUrl, equalTo(expectedUrl));
}
@ -81,7 +101,7 @@ public class TestPlainAuthRequestUrlBuilder {
Map<String, String> options = ImmutableMap.of("foo", "bar");
urlBuilder.buildAuthRequestUrl(serverConfig, clientConfig, "example.com", "", "", options);
urlBuilder.buildAuthRequestUrl(serverConfig, clientConfig, "example.com", "", "", options, null);
}
}

View File

@ -82,6 +82,7 @@ public class TestSignedAuthRequestUrlBuilder {
"9Z4qwjwbsnn4j2WBii3RL-Us2lGVkY8fkFzme1z0HbIkfz0Y6mqnOYtqc0X4jfcKoAC8Q";
private String alg = "RS256";
private String kid = "2011-04-29";
private String loginHint = "bob";
private DefaultJWTSigningAndValidationService signingAndValidationService;
@ -116,7 +117,7 @@ public class TestSignedAuthRequestUrlBuilder {
@Test
public void buildAuthRequestUrl() {
String requestUri = urlBuilder.buildAuthRequestUrl(serverConfig, clientConfig, redirectUri, nonce, state, options);
String requestUri = urlBuilder.buildAuthRequestUrl(serverConfig, clientConfig, redirectUri, nonce, state, options, null);
// parsing the result
UriComponentsBuilder builder = null;
@ -152,11 +153,51 @@ public class TestSignedAuthRequestUrlBuilder {
}
}
@Test
public void buildAuthRequestUrl_withLoginHint() {
String requestUri = urlBuilder.buildAuthRequestUrl(serverConfig, clientConfig, redirectUri, nonce, state, options, loginHint);
// parsing the result
UriComponentsBuilder builder = null;
try {
builder = UriComponentsBuilder.fromUri(new URI(requestUri));
} catch (URISyntaxException e1) {
fail("URISyntaxException was thrown.");
}
UriComponents components = builder.build();
String jwtString = components.getQueryParams().get("request").get(0);
ReadOnlyJWTClaimsSet claims = null;
try {
SignedJWT jwt = SignedJWT.parse(jwtString);
claims = jwt.getJWTClaimsSet();
} catch (ParseException e) {
fail("ParseException was thrown.");
}
assertEquals(responseType, claims.getClaim("response_type"));
assertEquals(clientConfig.getClientId(), claims.getClaim("client_id"));
List<String> scopeList = Arrays.asList(((String) claims.getClaim("scope")).split(" "));
assertTrue(scopeList.containsAll(clientConfig.getScope()));
assertEquals(redirectUri, claims.getClaim("redirect_uri"));
assertEquals(nonce, claims.getClaim("nonce"));
assertEquals(state, claims.getClaim("state"));
for (String claim : options.keySet()) {
assertEquals(options.get(claim), claims.getClaim(claim));
}
assertEquals(loginHint, claims.getClaim("login_hint"));
}
@Test(expected = AuthenticationServiceException.class)
public void buildAuthRequestUrl_badUri() {
Mockito.when(serverConfig.getAuthorizationEndpointUri()).thenReturn("e=mc^2");
urlBuilder.buildAuthRequestUrl(serverConfig, clientConfig, "example.com", "", "", options);
urlBuilder.buildAuthRequestUrl(serverConfig, clientConfig, "example.com", "", "", options, null);
}
}