001/* 002 * Copyright 2022 Anyware Services 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.ametys.plugins.extrausermgt.authentication.oidc; 017 018import java.io.InputStream; 019import java.net.URI; 020import java.net.URL; 021import java.nio.charset.StandardCharsets; 022import java.util.Map; 023 024import org.apache.commons.io.IOUtils; 025 026import org.ametys.runtime.authentication.AccessDeniedException; 027 028import com.nimbusds.oauth2.sdk.Scope; 029import com.nimbusds.openid.connect.sdk.OIDCScopeValue; 030import com.nimbusds.openid.connect.sdk.op.OIDCProviderMetadata; 031 032 033/** 034 * Sign in through an OIDC application (finding URIs by itself) using the OpenId Connect protocol. 035 */ 036public class AutoDiscoveringOIDCCredentialProvider extends AbstractOIDCCredentialProvider 037{ 038 /** 039 * Returns the provider meta data which contains the URIs retrieved from the "/.well-known/openid-configuration" of the issuer 040 * @return The provider meta data which contains the URIs 041 */ 042 private OIDCProviderMetadata _getProviderMetadata(URI issuerURI) throws Exception 043 { 044 URL providerConfigurationURL = issuerURI.resolve(".well-known/openid-configuration").toURL(); 045 try (InputStream stream = providerConfigurationURL.openStream()) 046 { 047 // Read all data from URL 048 String providerInfo = IOUtils.toString(stream, StandardCharsets.UTF_8); 049 return OIDCProviderMetadata.parse(providerInfo); 050 } 051 } 052 053 @Override 054 protected void initUrisScope() throws AccessDeniedException 055 { 056 Map<String, Object> paramValues = getParameterValues(); 057 try 058 { 059 URI issuerURI = URI.create((String) paramValues.get("authentication.oidc.issuerURI")); 060 OIDCProviderMetadata providerMetadata = _getProviderMetadata(issuerURI); 061 _authUri = providerMetadata.getAuthorizationEndpointURI(); 062 _tokenEndpointUri = providerMetadata.getTokenEndpointURI(); 063 _iss = providerMetadata.getIssuer(); 064 _jwkSetURL = providerMetadata.getJWKSetURI().toURL(); 065 _userInfoEndpoint = providerMetadata.getUserInfoEndpointURI(); 066 067 _scope = Scope.parse((String) paramValues.get("authentication.oidc.scopes")); 068 _scope.add(OIDCScopeValue.OPENID); 069 } 070 catch (Exception e) 071 { 072 getLogger().error("Encountered a problem while retrieving provider metadata", e); 073 throw new AccessDeniedException("Encountered a problem while retrieving provider metadata"); 074 } 075 } 076}