001package com.nimbusds.openid.connect.sdk.id; 002 003 004import java.io.IOException; 005import java.net.URI; 006import java.util.List; 007import java.util.Set; 008 009import com.nimbusds.jose.util.Resource; 010import com.nimbusds.jose.util.ResourceRetriever; 011import com.nimbusds.oauth2.sdk.GeneralException; 012import com.nimbusds.oauth2.sdk.util.JSONArrayUtils; 013 014 015/** 016 * Sector identifier URI validator. 017 * 018 * <p>Related specifications: 019 * 020 * <ul> 021 * <li>OpenID Connect Core 1.0, section 8.1. 022 * <li>OpenID Connect Dynamic Client Registration 1.0, section 5. 023 * </ul> 024 */ 025public class SectorIDURIValidator { 026 027 028 /** 029 * The URL resource retriever. 030 */ 031 private final ResourceRetriever resourceRetriever; 032 033 034 /** 035 * Creates a new sector identifier URI validator. 036 * 037 * @param resourceRetriever The URL resource retriever to use. Must not 038 * be {@code null}. 039 */ 040 public SectorIDURIValidator(final ResourceRetriever resourceRetriever) { 041 if (resourceRetriever == null) { 042 throw new IllegalArgumentException("The resource retriever must not be null"); 043 } 044 this.resourceRetriever = resourceRetriever; 045 } 046 047 048 /** 049 * Returns the URL resource retriever. 050 * 051 * @return The resource retriever. 052 */ 053 public ResourceRetriever getResourceRetriever() { 054 return resourceRetriever; 055 } 056 057 058 /** 059 * Validates the specified sector identifier URI by ensuring it lists 060 * all specified redirection URIs. 061 * 062 * 063 * @param sectorURI The sector identifier URI. Must not be 064 * {@code null}. 065 * @param redirectURIs The redirection URIs of the client. Must not be 066 * {@code null}. 067 * 068 * @throws GeneralException If validation failed. 069 */ 070 public void validate(final URI sectorURI, final Set<URI> redirectURIs) 071 throws GeneralException { 072 073 Resource resource; 074 075 try { 076 resource = resourceRetriever.retrieveResource(sectorURI.toURL()); 077 } catch (IOException e) { 078 throw new GeneralException("Couldn't retrieve the sector ID JSON document: " + e.getMessage(), e); 079 } 080 081 if (resource.getContentType() == null) { 082 throw new GeneralException("Couldn't validate sector ID URI: Missing Content-Type"); 083 } 084 085 if (! resource.getContentType().toLowerCase().startsWith("application/json")) { 086 throw new GeneralException("Couldn't validate sector ID URI: Content-Type must be application/json, found " + resource.getContentType()); 087 } 088 089 List<URI> uriList = JSONArrayUtils.toURIList(JSONArrayUtils.parse(resource.getContent())); 090 091 for (URI uri: redirectURIs) { 092 093 if (! uriList.contains(uri)) { 094 throw new GeneralException("Sector ID URI validation failed: Redirect URI " + uri + " is missing from published JSON array at sector ID URI " + sectorURI); 095 } 096 } 097 } 098}