diff --git a/openid-connect-common/src/main/java/org/mitre/openid/connect/model/DefaultUserInfo.java b/openid-connect-common/src/main/java/org/mitre/openid/connect/model/DefaultUserInfo.java index 4fe7d914a..a55e3f9c1 100644 --- a/openid-connect-common/src/main/java/org/mitre/openid/connect/model/DefaultUserInfo.java +++ b/openid-connect-common/src/main/java/org/mitre/openid/connect/model/DefaultUserInfo.java @@ -33,15 +33,19 @@ import com.google.gson.JsonObject; @Entity @Table(name="user_info") @NamedQueries({ - @NamedQuery(name=DefaultUserInfo.QUERY_BY_USERNAME, query = "select u from DefaultUserInfo u WHERE u.preferredUsername = :" + DefaultUserInfo.PARAM_USERNAME) + @NamedQuery(name=DefaultUserInfo.QUERY_BY_USERNAME, query = "select u from DefaultUserInfo u WHERE u.preferredUsername = :" + DefaultUserInfo.PARAM_USERNAME), + @NamedQuery(name=DefaultUserInfo.QUERY_BY_EMAIL, query = "select u from DefaultUserInfo u WHERE u.email = :" + DefaultUserInfo.PARAM_EMAIL) }) public class DefaultUserInfo implements UserInfo { public static final String QUERY_BY_USERNAME = "DefaultUserInfo.getByUsername"; + public static final String QUERY_BY_EMAIL = "DefaultUserInfo.getByEmailAddress"; public static final String PARAM_USERNAME = "username"; + public static final String PARAM_EMAIL = "email"; private static final long serialVersionUID = 6078310513185681918L; + private Long id; private String sub; private String preferredUsername; diff --git a/openid-connect-common/src/main/java/org/mitre/openid/connect/repository/UserInfoRepository.java b/openid-connect-common/src/main/java/org/mitre/openid/connect/repository/UserInfoRepository.java index dbfc75af0..02f91b2f0 100644 --- a/openid-connect-common/src/main/java/org/mitre/openid/connect/repository/UserInfoRepository.java +++ b/openid-connect-common/src/main/java/org/mitre/openid/connect/repository/UserInfoRepository.java @@ -33,4 +33,13 @@ public interface UserInfoRepository { */ public UserInfo getByUsername(String username); + /** + * + * Get the UserInfo object by its email field + * + * @param email + * @return + */ + public UserInfo getByEmailAddress(String email); + } diff --git a/openid-connect-common/src/main/java/org/mitre/openid/connect/service/UserInfoService.java b/openid-connect-common/src/main/java/org/mitre/openid/connect/service/UserInfoService.java index 43ddc628c..899923533 100644 --- a/openid-connect-common/src/main/java/org/mitre/openid/connect/service/UserInfoService.java +++ b/openid-connect-common/src/main/java/org/mitre/openid/connect/service/UserInfoService.java @@ -44,4 +44,12 @@ public interface UserInfoService { */ public UserInfo getByUsernameAndClientId(String username, String clientId); + /** + * Get the user registered at this server with the given email address. + * + * @param email + * @return + */ + public UserInfo getByEmailAddress(String email); + } diff --git a/openid-connect-server/src/main/java/org/mitre/discovery/web/DiscoveryEndpoint.java b/openid-connect-server/src/main/java/org/mitre/discovery/web/DiscoveryEndpoint.java index 10ce60f20..0f181fa89 100644 --- a/openid-connect-server/src/main/java/org/mitre/discovery/web/DiscoveryEndpoint.java +++ b/openid-connect-server/src/main/java/org/mitre/discovery/web/DiscoveryEndpoint.java @@ -116,25 +116,37 @@ public class DiscoveryEndpoint { if (resourceUri != null && resourceUri.getScheme() != null && resourceUri.getScheme().equals("acct")) { - // acct: URI - - UserInfo user = userService.getByUsername(resourceUri.getUserInfo()); // first part is the username + // acct: URI (email address format) + // check on email addresses first + UserInfo user = userService.getByEmailAddress(resourceUri.getUserInfo() + "@" + resourceUri.getHost()); + if (user == null) { - logger.info("User not found: " + resource); - model.addAttribute(HttpCodeView.CODE, HttpStatus.NOT_FOUND); - return HttpCodeView.VIEWNAME; + // user wasn't found, see if the local part of the username matches, plus our issuer host + + user = userService.getByUsername(resourceUri.getUserInfo()); // first part is the username + + if (user != null) { + // username matched, check the host component + UriComponents issuerComponents = UriComponentsBuilder.fromHttpUrl(config.getIssuer()).build(); + if (!Strings.nullToEmpty(issuerComponents.getHost()) + .equals(Strings.nullToEmpty(resourceUri.getHost()))) { + logger.info("Host mismatch, expected " + issuerComponents.getHost() + " got " + resourceUri.getHost()); + model.addAttribute(HttpCodeView.CODE, HttpStatus.NOT_FOUND); + return HttpCodeView.VIEWNAME; + } + + } else { + + // if the user's still null, punt and say we didn't find them + + logger.info("User not found: " + resource); + model.addAttribute(HttpCodeView.CODE, HttpStatus.NOT_FOUND); + return HttpCodeView.VIEWNAME; + } + } - UriComponents issuerComponents = UriComponentsBuilder.fromHttpUrl(config.getIssuer()).build(); - if (!Strings.nullToEmpty(issuerComponents.getHost()) - .equals(Strings.nullToEmpty(resourceUri.getHost()))) { - logger.info("Host mismatch, expected " + issuerComponents.getHost() + " got " + resourceUri.getHost()); - model.addAttribute(HttpCodeView.CODE, HttpStatus.NOT_FOUND); - return HttpCodeView.VIEWNAME; - } - - } else { logger.info("Unknown URI format: " + resource); model.addAttribute(HttpCodeView.CODE, HttpStatus.NOT_FOUND); @@ -142,7 +154,7 @@ public class DiscoveryEndpoint { } } - // if we got here, then we're good + // if we got here, then we're good, return ourselves model.addAttribute("resource", resource); model.addAttribute("issuer", config.getIssuer()); diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/repository/impl/JpaUserInfoRepository.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/repository/impl/JpaUserInfoRepository.java index 4acb2687a..59fb332c4 100644 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/repository/impl/JpaUserInfoRepository.java +++ b/openid-connect-server/src/main/java/org/mitre/openid/connect/repository/impl/JpaUserInfoRepository.java @@ -51,4 +51,15 @@ public class JpaUserInfoRepository implements UserInfoRepository { } + /** + * Get a single UserInfo object by its email address + */ + @Override + public UserInfo getByEmailAddress(String email) { + TypedQuery query = manager.createNamedQuery(DefaultUserInfo.QUERY_BY_EMAIL, DefaultUserInfo.class); + query.setParameter(DefaultUserInfo.PARAM_EMAIL, email); + + return getSingleResult(query.getResultList()); + } + } diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/DefaultUserInfoService.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/DefaultUserInfoService.java index d5cfd3d53..463e9c094 100644 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/DefaultUserInfoService.java +++ b/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/DefaultUserInfoService.java @@ -69,4 +69,9 @@ public class DefaultUserInfoService implements UserInfoService { } + @Override + public UserInfo getByEmailAddress(String email) { + return userInfoRepository.getByEmailAddress(email); + } + }