init commit for Webfinger normilizer utility class.
parent
93c3e7906f
commit
eaa7298ef1
|
@ -22,14 +22,13 @@ package org.mitre.openid.connect.client.service.impl;
|
|||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.utils.URIBuilder;
|
||||
import org.apache.http.impl.client.DefaultHttpClient;
|
||||
import org.mitre.discovery.util.WebfingerURLNormalizer;
|
||||
import org.mitre.openid.connect.client.model.IssuerServiceResponse;
|
||||
import org.mitre.openid.connect.client.service.IssuerService;
|
||||
import org.slf4j.Logger;
|
||||
|
@ -38,7 +37,6 @@ import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
|
|||
import org.springframework.security.authentication.AuthenticationServiceException;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
import org.springframework.web.util.UriComponents;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
|
@ -58,9 +56,6 @@ public class WebfingerIssuerService implements IssuerService {
|
|||
|
||||
private static Logger logger = LoggerFactory.getLogger(WebfingerIssuerService.class);
|
||||
|
||||
// pattern used to parse user input; we can't use the built-in java URI parser
|
||||
private static final Pattern pattern = Pattern.compile("^((https|acct|http|mailto):(//)?)?((([^@]+)@)?(([^:]+)(:(\\d*))?))([^\\?]+)?(\\?([^#]+))?(#(.*))?$");
|
||||
|
||||
// map of user input -> issuer, loaded dynamically from webfinger discover
|
||||
private LoadingCache<UriComponents, String> issuers;
|
||||
|
||||
|
@ -90,7 +85,7 @@ public class WebfingerIssuerService implements IssuerService {
|
|||
String identifier = request.getParameter(parameterName);
|
||||
if (!Strings.isNullOrEmpty(identifier)) {
|
||||
try {
|
||||
String issuer = issuers.get(normalizeResource(identifier));
|
||||
String issuer = issuers.get(WebfingerURLNormalizer.normalizeResource(identifier));
|
||||
if (!whitelist.isEmpty() && !whitelist.contains(issuer)) {
|
||||
throw new AuthenticationServiceException("Whitelist was nonempty, issuer was not in whitelist: " + issuer);
|
||||
}
|
||||
|
@ -111,71 +106,6 @@ public class WebfingerIssuerService implements IssuerService {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize the resource string as per OIDC Discovery.
|
||||
* @param identifier
|
||||
* @return the normalized string, or null if the string can't be normalized
|
||||
*/
|
||||
private UriComponents normalizeResource(String identifier) {
|
||||
// try to parse the URI
|
||||
// NOTE: we can't use the Java built-in URI class because it doesn't split the parts appropriately
|
||||
|
||||
if (Strings.isNullOrEmpty(identifier)) {
|
||||
logger.warn("Can't normalize null or empty URI: " + identifier);
|
||||
return null; // nothing we can do
|
||||
} else {
|
||||
|
||||
//UriComponentsBuilder builder = UriComponentsBuilder.fromUriString(identifier);
|
||||
UriComponentsBuilder builder = UriComponentsBuilder.newInstance();
|
||||
|
||||
//Pattern regex = Pattern.compile("^(([^:/?#]+):)?(//(([^@/]*)@)?([^/?#:]*)(:(\\d*))?)?([^?#]*)(\\?([^#]*))?(#(.*))?");
|
||||
Matcher m = pattern.matcher(identifier);
|
||||
if (m.matches()) {
|
||||
builder.scheme(m.group(2));
|
||||
builder.userInfo(m.group(6));
|
||||
builder.host(m.group(8));
|
||||
String port = m.group(10);
|
||||
if (!Strings.isNullOrEmpty(port)) {
|
||||
builder.port(Integer.parseInt(port));
|
||||
}
|
||||
builder.path(m.group(11));
|
||||
builder.query(m.group(13));
|
||||
builder.fragment(m.group(15)); // we throw away the hash, but this is the group it would be if we kept it
|
||||
} else {
|
||||
// doesn't match the pattern, throw it out
|
||||
logger.warn("Parser couldn't match input: " + identifier);
|
||||
return null;
|
||||
}
|
||||
|
||||
UriComponents n = builder.build();
|
||||
|
||||
if (Strings.isNullOrEmpty(n.getScheme())) {
|
||||
if (!Strings.isNullOrEmpty(n.getUserInfo())
|
||||
&& Strings.isNullOrEmpty(n.getPath())
|
||||
&& Strings.isNullOrEmpty(n.getQuery())
|
||||
&& n.getPort() < 0) {
|
||||
|
||||
// scheme empty, userinfo is not empty, path/query/port are empty
|
||||
// set to "acct" (rule 2)
|
||||
builder.scheme("acct");
|
||||
|
||||
} else {
|
||||
// scheme is empty, but rule 2 doesn't apply
|
||||
// set scheme to "https" (rule 3)
|
||||
builder.scheme("https");
|
||||
}
|
||||
}
|
||||
|
||||
// fragment must be stripped (rule 4)
|
||||
builder.fragment(null);
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return the parameterName
|
||||
*/
|
||||
|
|
|
@ -0,0 +1,115 @@
|
|||
/*******************************************************************************
|
||||
* Copyright 2013 The MITRE Corporation
|
||||
* and the MIT Kerberos and Internet Trust Consortium
|
||||
*
|
||||
* 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 org.mitre.discovery.util;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.web.util.UriComponents;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
|
||||
/**
|
||||
* Provides utility methods for normalizing and parsing URIs for use with Webfinger Discovery.
|
||||
*
|
||||
* @author wkim
|
||||
*
|
||||
*/
|
||||
public class WebfingerURLNormalizer {
|
||||
|
||||
private static Logger logger = LoggerFactory.getLogger(WebfingerURLNormalizer.class);
|
||||
|
||||
// pattern used to parse user input; we can't use the built-in java URI parser
|
||||
private static final Pattern pattern = Pattern.compile("^((https|acct|http|mailto):(//)?)?((([^@]+)@)?(([^:]+)(:(\\d*))?))([^\\?]+)?(\\?([^#]+))?(#(.*))?$");
|
||||
|
||||
|
||||
/**
|
||||
* Private constructor to prevent instantiation.
|
||||
*/
|
||||
private WebfingerURLNormalizer() {
|
||||
// intentionally blank
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize the resource string as per OIDC Discovery.
|
||||
* @param identifier
|
||||
* @return the normalized string, or null if the string can't be normalized
|
||||
*/
|
||||
public static UriComponents normalizeResource(String identifier) {
|
||||
// try to parse the URI
|
||||
// NOTE: we can't use the Java built-in URI class because it doesn't split the parts appropriately
|
||||
|
||||
if (Strings.isNullOrEmpty(identifier)) {
|
||||
logger.warn("Can't normalize null or empty URI: " + identifier);
|
||||
return null; // nothing we can do
|
||||
} else {
|
||||
|
||||
//UriComponentsBuilder builder = UriComponentsBuilder.fromUriString(identifier);
|
||||
UriComponentsBuilder builder = UriComponentsBuilder.newInstance();
|
||||
|
||||
//Pattern regex = Pattern.compile("^(([^:/?#]+):)?(//(([^@/]*)@)?([^/?#:]*)(:(\\d*))?)?([^?#]*)(\\?([^#]*))?(#(.*))?");
|
||||
Matcher m = pattern.matcher(identifier);
|
||||
if (m.matches()) {
|
||||
builder.scheme(m.group(2));
|
||||
builder.userInfo(m.group(6));
|
||||
builder.host(m.group(8));
|
||||
String port = m.group(10);
|
||||
if (!Strings.isNullOrEmpty(port)) {
|
||||
builder.port(Integer.parseInt(port));
|
||||
}
|
||||
builder.path(m.group(11));
|
||||
builder.query(m.group(13));
|
||||
builder.fragment(m.group(15)); // we throw away the hash, but this is the group it would be if we kept it
|
||||
} else {
|
||||
// doesn't match the pattern, throw it out
|
||||
logger.warn("Parser couldn't match input: " + identifier);
|
||||
return null;
|
||||
}
|
||||
|
||||
UriComponents n = builder.build();
|
||||
|
||||
if (Strings.isNullOrEmpty(n.getScheme())) {
|
||||
if (!Strings.isNullOrEmpty(n.getUserInfo())
|
||||
&& Strings.isNullOrEmpty(n.getPath())
|
||||
&& Strings.isNullOrEmpty(n.getQuery())
|
||||
&& n.getPort() < 0) {
|
||||
|
||||
// scheme empty, userinfo is not empty, path/query/port are empty
|
||||
// set to "acct" (rule 2)
|
||||
builder.scheme("acct");
|
||||
|
||||
} else {
|
||||
// scheme is empty, but rule 2 doesn't apply
|
||||
// set scheme to "https" (rule 3)
|
||||
builder.scheme("https");
|
||||
}
|
||||
}
|
||||
|
||||
// fragment must be stripped (rule 4)
|
||||
builder.fragment(null);
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
Loading…
Reference in New Issue