From 960ede2c5f7dd4bf8410f5907d4d681928ea87b1 Mon Sep 17 00:00:00 2001 From: Florian Buchmeier Date: Thu, 15 Apr 2021 18:01:12 +0200 Subject: [PATCH 01/12] quick fix for GET request on userinfo endpoint --- .../pwm/http/servlet/oauth/OAuthMachine.java | 67 ++++++++++++++++++- 1 file changed, 66 insertions(+), 1 deletion(-) diff --git a/server/src/main/java/password/pwm/http/servlet/oauth/OAuthMachine.java b/server/src/main/java/password/pwm/http/servlet/oauth/OAuthMachine.java index 1c556c8eb8..4087638c19 100644 --- a/server/src/main/java/password/pwm/http/servlet/oauth/OAuthMachine.java +++ b/server/src/main/java/password/pwm/http/servlet/oauth/OAuthMachine.java @@ -233,7 +233,7 @@ String makeOAuthGetUserInfoRequest( final Map requestParams = new HashMap<>(); requestParams.put( config.readAppProperty( AppProperty.HTTP_PARAM_OAUTH_ACCESS_TOKEN ), accessToken ); requestParams.put( config.readAppProperty( AppProperty.HTTP_PARAM_OAUTH_ATTRIBUTES ), settings.getDnAttributeName() ); - restResults = makeHttpRequest( pwmRequest, "OAuth userinfo", settings, requestUrl, requestParams, accessToken ); + restResults = makeHttpGetRequest( pwmRequest, "OAuth userinfo", settings, requestUrl, requestParams, accessToken ); } final String resultBody = restResults.getBody(); @@ -320,6 +320,71 @@ private static PwmHttpClientResponse makeHttpRequest( return pwmHttpClientResponse; } + private static PwmHttpClientResponse makeHttpGetRequest( + final PwmRequest pwmRequest, + final String debugText, + final OAuthSettings settings, + final String requestUrl, + final Map requestParams, + final String accessToken + ) + throws PwmUnrecoverableException + { + final String requestBody = PwmURL.encodeParametersToFormBody( requestParams ); + final List certs = settings.getCertificates(); + + final PwmHttpClientRequest pwmHttpClientRequest; + { + final Map headers = new HashMap<>( ); + if ( StringUtil.isEmpty( accessToken ) ) + { + headers.put( HttpHeader.Authorization.getHttpName(), + new BasicAuthInfo( settings.getClientID(), settings.getSecret() ).toAuthHeader() ); + } + else + { + headers.put( HttpHeader.Authorization.getHttpName(), + "Bearer " + accessToken ); + } + headers.put( HttpHeader.ContentType.getHttpName(), HttpContentType.form.getHeaderValueWithEncoding() ); + + pwmHttpClientRequest = PwmHttpClientRequest.builder() + .method( HttpMethod.GET ) + .url( requestUrl ) + .body( requestBody ) + .headers( headers ) + .build(); + } + + final PwmHttpClientResponse pwmHttpClientResponse; + try + { + final PwmHttpClientConfiguration config = PwmHttpClientConfiguration.builder() + .trustManagerType( PwmHttpClientConfiguration.TrustManagerType.configuredCertificates ) + .certificates( JavaHelper.isEmpty( certs ) ? null : certs ) + .maskBodyDebugOutput( true ) + .build(); + final PwmHttpClient pwmHttpClient = pwmRequest.getPwmApplication().getHttpClientService().getPwmHttpClient( config ); + pwmHttpClientResponse = pwmHttpClient.makeRequest( pwmHttpClientRequest, pwmRequest.getLabel() ); + } + catch ( final PwmException e ) + { + final String errorMsg = "error during " + debugText + " http request to oauth server, remote error: " + e.getErrorInformation().toDebugStr(); + throw new PwmUnrecoverableException( new ErrorInformation( PwmError.ERROR_OAUTH_ERROR, errorMsg ) ); + } + + + if ( pwmHttpClientResponse.getStatusCode() != HttpStatus.SC_OK ) + { + throw new PwmUnrecoverableException( new ErrorInformation( + PwmError.ERROR_OAUTH_ERROR, + "unexpected HTTP status code (" + pwmHttpClientResponse.getStatusCode() + ") during " + debugText + " request to " + requestUrl + ) ); + } + + return pwmHttpClientResponse; + } + private static String figureOauthSelfEndPointUrl( final PwmRequest pwmRequest ) { final String debugSource; From 288a757c771e56c700e65a1fd2864f57900d3c1b Mon Sep 17 00:00:00 2001 From: Florian Buchmeier Date: Fri, 16 Apr 2021 11:15:05 +0200 Subject: [PATCH 02/12] simplified GET requests for userinfo endpoint --- .../pwm/http/servlet/oauth/OAuthMachine.java | 80 +++---------------- 1 file changed, 9 insertions(+), 71 deletions(-) diff --git a/server/src/main/java/password/pwm/http/servlet/oauth/OAuthMachine.java b/server/src/main/java/password/pwm/http/servlet/oauth/OAuthMachine.java index 4087638c19..404af32c1c 100644 --- a/server/src/main/java/password/pwm/http/servlet/oauth/OAuthMachine.java +++ b/server/src/main/java/password/pwm/http/servlet/oauth/OAuthMachine.java @@ -171,7 +171,7 @@ OAuthResolveResults makeOAuthResolveRequest( requestParams.put( config.readAppProperty( AppProperty.HTTP_PARAM_OAUTH_CLIENT_ID ), clientID ); requestParams.put( config.readAppProperty( AppProperty.HTTP_PARAM_OAUTH_CLIENT_SECRET ), settings.getSecret().getStringValue() ); - final PwmHttpClientResponse restResults = makeHttpRequest( pwmRequest, "oauth code resolver", settings, requestUrl, requestParams, null ); + final PwmHttpClientResponse restResults = makeHttpRequest( pwmRequest, "oauth code resolver", settings, requestUrl, requestParams, null, HttpMethod.POST ); final OAuthResolveResults results = resolveResultsFromResponseBody( pwmRequest, restResults.getBody() ); @@ -215,7 +215,7 @@ private OAuthResolveResults makeOAuthRefreshRequest( requestParams.put( config.readAppProperty( AppProperty.HTTP_PARAM_OAUTH_REFRESH_TOKEN ), refreshCode ); requestParams.put( config.readAppProperty( AppProperty.HTTP_PARAM_OAUTH_GRANT_TYPE ), grantType ); - final PwmHttpClientResponse restResults = makeHttpRequest( pwmRequest, "OAuth refresh resolver", settings, requestUrl, requestParams, null ); + final PwmHttpClientResponse restResults = makeHttpRequest( pwmRequest, "OAuth refresh resolver", settings, requestUrl, requestParams, null, HttpMethod.POST ); return resolveResultsFromResponseBody( pwmRequest, restResults.getBody() ); } @@ -231,9 +231,10 @@ String makeOAuthGetUserInfoRequest( final Configuration config = pwmRequest.getConfig(); final String requestUrl = settings.getAttributesUrl(); final Map requestParams = new HashMap<>(); + final HttpMethod method = HttpMethod.GET; requestParams.put( config.readAppProperty( AppProperty.HTTP_PARAM_OAUTH_ACCESS_TOKEN ), accessToken ); requestParams.put( config.readAppProperty( AppProperty.HTTP_PARAM_OAUTH_ATTRIBUTES ), settings.getDnAttributeName() ); - restResults = makeHttpGetRequest( pwmRequest, "OAuth userinfo", settings, requestUrl, requestParams, accessToken ); + restResults = makeHttpRequest( pwmRequest, "OAuth userinfo", settings, requestUrl, requestParams, accessToken, method ); } final String resultBody = restResults.getBody(); @@ -261,72 +262,8 @@ private static PwmHttpClientResponse makeHttpRequest( final OAuthSettings settings, final String requestUrl, final Map requestParams, - final String accessToken - ) - throws PwmUnrecoverableException - { - final String requestBody = PwmURL.encodeParametersToFormBody( requestParams ); - final List certs = settings.getCertificates(); - - final PwmHttpClientRequest pwmHttpClientRequest; - { - final Map headers = new HashMap<>( ); - if ( StringUtil.isEmpty( accessToken ) ) - { - headers.put( HttpHeader.Authorization.getHttpName(), - new BasicAuthInfo( settings.getClientID(), settings.getSecret() ).toAuthHeader() ); - } - else - { - headers.put( HttpHeader.Authorization.getHttpName(), - "Bearer " + accessToken ); - } - headers.put( HttpHeader.ContentType.getHttpName(), HttpContentType.form.getHeaderValueWithEncoding() ); - - pwmHttpClientRequest = PwmHttpClientRequest.builder() - .method( HttpMethod.POST ) - .url( requestUrl ) - .body( requestBody ) - .headers( headers ) - .build(); - } - - final PwmHttpClientResponse pwmHttpClientResponse; - try - { - final PwmHttpClientConfiguration config = PwmHttpClientConfiguration.builder() - .trustManagerType( PwmHttpClientConfiguration.TrustManagerType.configuredCertificates ) - .certificates( JavaHelper.isEmpty( certs ) ? null : certs ) - .maskBodyDebugOutput( true ) - .build(); - final PwmHttpClient pwmHttpClient = pwmRequest.getPwmApplication().getHttpClientService().getPwmHttpClient( config ); - pwmHttpClientResponse = pwmHttpClient.makeRequest( pwmHttpClientRequest, pwmRequest.getLabel() ); - } - catch ( final PwmException e ) - { - final String errorMsg = "error during " + debugText + " http request to oauth server, remote error: " + e.getErrorInformation().toDebugStr(); - throw new PwmUnrecoverableException( new ErrorInformation( PwmError.ERROR_OAUTH_ERROR, errorMsg ) ); - } - - - if ( pwmHttpClientResponse.getStatusCode() != HttpStatus.SC_OK ) - { - throw new PwmUnrecoverableException( new ErrorInformation( - PwmError.ERROR_OAUTH_ERROR, - "unexpected HTTP status code (" + pwmHttpClientResponse.getStatusCode() + ") during " + debugText + " request to " + requestUrl - ) ); - } - - return pwmHttpClientResponse; - } - - private static PwmHttpClientResponse makeHttpGetRequest( - final PwmRequest pwmRequest, - final String debugText, - final OAuthSettings settings, - final String requestUrl, - final Map requestParams, - final String accessToken + final String accessToken, + final HttpMethod method ) throws PwmUnrecoverableException { @@ -349,7 +286,7 @@ private static PwmHttpClientResponse makeHttpGetRequest( headers.put( HttpHeader.ContentType.getHttpName(), HttpContentType.form.getHeaderValueWithEncoding() ); pwmHttpClientRequest = PwmHttpClientRequest.builder() - .method( HttpMethod.GET ) + .method( method ) .url( requestUrl ) .body( requestBody ) .headers( headers ) @@ -546,7 +483,8 @@ private String figureUsernameGrantParam( } LOGGER.debug( sessionLabel, () -> "preparing to send username to OAuth /sign endpoint for future injection to /grant redirect" ); - final PwmHttpClientResponse restResults = makeHttpRequest( pwmRequest, "OAuth pre-inject username signing service", settings, signUrl, requestPayload, null ); + final PwmHttpClientResponse restResults = makeHttpRequest( pwmRequest, "OAuth pre-inject username signing service", settings, + signUrl, requestPayload, null, HttpMethod.POST ); final String resultBody = restResults.getBody(); final Map resultBodyMap = JsonUtil.deserializeStringMap( resultBody ); From 0bfd4b77a5022bd79dcfcf115a79953b8012ad4e Mon Sep 17 00:00:00 2001 From: Florian Buchmeier Date: Fri, 16 Apr 2021 13:38:31 +0200 Subject: [PATCH 03/12] added option to send either POST or GET requests to oauth userinfo endpoint --- .../password/pwm/config/Configuration.java | 14 ++++++++++++++ .../java/password/pwm/config/PwmSetting.java | 4 ++++ .../pwm/http/servlet/oauth/OAuthMachine.java | 4 ++-- .../pwm/http/servlet/oauth/OAuthSettings.java | 3 +++ .../password/pwm/config/PwmSetting.xml | 18 ++++++++++++++++++ .../password/pwm/i18n/PwmSetting.properties | 4 ++++ .../password/pwm/util/java/XmlFactoryTest.java | 2 +- .../config/stored/ConfigurationCleanerTest.xml | 8 ++++++++ .../password/pwm/util/java/XmlFactoryTest.xml | 8 ++++++++ 9 files changed, 62 insertions(+), 3 deletions(-) diff --git a/server/src/main/java/password/pwm/config/Configuration.java b/server/src/main/java/password/pwm/config/Configuration.java index 0dacd170fc..2bedea14d6 100644 --- a/server/src/main/java/password/pwm/config/Configuration.java +++ b/server/src/main/java/password/pwm/config/Configuration.java @@ -70,6 +70,7 @@ import password.pwm.util.secure.PwmRandom; import password.pwm.util.secure.PwmSecurityKey; import password.pwm.util.secure.SecureService; +import password.pwm.http.HttpMethod; import java.lang.reflect.InvocationTargetException; import java.security.cert.X509Certificate; @@ -363,6 +364,19 @@ public PrivateKeyCertificate readSettingAsPrivateKey( final PwmSetting setting ) return ( PrivateKeyCertificate ) readStoredValue( setting ).toNativeObject(); } + public HttpMethod readSettingAsHttpMethod( final PwmSetting setting ) + { + final password.pwm.config.option.HttpMethod method = readSettingAsEnum( setting, password.pwm.config.option.HttpMethod.class ); + if ( method == password.pwm.config.option.HttpMethod.POST ) + { + return HttpMethod.POST; + } + else + { + return HttpMethod.GET; + } + } + private PwmSecurityKey tempInstanceKey = null; public PwmSecurityKey getSecurityKey( ) throws PwmUnrecoverableException diff --git a/server/src/main/java/password/pwm/config/PwmSetting.java b/server/src/main/java/password/pwm/config/PwmSetting.java index 8e815c1335..e4dd11a644 100644 --- a/server/src/main/java/password/pwm/config/PwmSetting.java +++ b/server/src/main/java/password/pwm/config/PwmSetting.java @@ -810,6 +810,8 @@ public enum PwmSetting "recovery.oauth.idserver.codeResolveUrl", PwmSettingSyntax.STRING, PwmSettingCategory.RECOVERY_OAUTH ), RECOVERY_OAUTH_ID_ATTRIBUTES_URL( "recovery.oauth.idserver.attributesUrl", PwmSettingSyntax.STRING, PwmSettingCategory.RECOVERY_OAUTH ), + RECOVERY_OAUTH_ID_ATTRIBUTES_METHOD( + "recovery.oauth.idserver.attributesMethod", PwmSettingSyntax.SELECT, PwmSettingCategory.RECOVERY_OAUTH ), RECOVERY_OAUTH_ID_CERTIFICATE( "recovery.oauth.idserver.serverCerts", PwmSettingSyntax.X509CERT, PwmSettingCategory.RECOVERY_OAUTH ), RECOVERY_OAUTH_ID_CLIENTNAME( @@ -1178,6 +1180,8 @@ public enum PwmSetting "oauth.idserver.codeResolveUrl", PwmSettingSyntax.STRING, PwmSettingCategory.OAUTH ), OAUTH_ID_ATTRIBUTES_URL( "oauth.idserver.attributesUrl", PwmSettingSyntax.STRING, PwmSettingCategory.OAUTH ), + OAUTH_ID_ATTRIBUTES_METHOD( + "oauth.idserver.attributesMethod", PwmSettingSyntax.SELECT, PwmSettingCategory.OAUTH ), OAUTH_ID_CERTIFICATE( "oauth.idserver.serverCerts", PwmSettingSyntax.X509CERT, PwmSettingCategory.OAUTH ), OAUTH_ID_CLIENTNAME( diff --git a/server/src/main/java/password/pwm/http/servlet/oauth/OAuthMachine.java b/server/src/main/java/password/pwm/http/servlet/oauth/OAuthMachine.java index 404af32c1c..ec24d8bc96 100644 --- a/server/src/main/java/password/pwm/http/servlet/oauth/OAuthMachine.java +++ b/server/src/main/java/password/pwm/http/servlet/oauth/OAuthMachine.java @@ -230,11 +230,11 @@ String makeOAuthGetUserInfoRequest( { final Configuration config = pwmRequest.getConfig(); final String requestUrl = settings.getAttributesUrl(); + final HttpMethod requestMethod = settings.getAttributesMethod(); final Map requestParams = new HashMap<>(); - final HttpMethod method = HttpMethod.GET; requestParams.put( config.readAppProperty( AppProperty.HTTP_PARAM_OAUTH_ACCESS_TOKEN ), accessToken ); requestParams.put( config.readAppProperty( AppProperty.HTTP_PARAM_OAUTH_ATTRIBUTES ), settings.getDnAttributeName() ); - restResults = makeHttpRequest( pwmRequest, "OAuth userinfo", settings, requestUrl, requestParams, accessToken, method ); + restResults = makeHttpRequest( pwmRequest, "OAuth userinfo", settings, requestUrl, requestParams, accessToken, requestMethod ); } final String resultBody = restResults.getBody(); diff --git a/server/src/main/java/password/pwm/http/servlet/oauth/OAuthSettings.java b/server/src/main/java/password/pwm/http/servlet/oauth/OAuthSettings.java index 443c7e6300..159c7d9662 100644 --- a/server/src/main/java/password/pwm/http/servlet/oauth/OAuthSettings.java +++ b/server/src/main/java/password/pwm/http/servlet/oauth/OAuthSettings.java @@ -26,6 +26,7 @@ import password.pwm.config.PwmSetting; import password.pwm.config.profile.ForgottenPasswordProfile; import password.pwm.util.PasswordData; +import password.pwm.http.HttpMethod; import java.io.Serializable; import java.security.cert.X509Certificate; @@ -38,6 +39,7 @@ public class OAuthSettings implements Serializable private String loginURL; private String codeResolveUrl; private String attributesUrl; + private HttpMethod attributesMethod; private String scope; private String clientID; private PasswordData secret; @@ -62,6 +64,7 @@ public static OAuthSettings forSSOAuthentication( final Configuration config ) .loginURL( config.readSettingAsString( PwmSetting.OAUTH_ID_LOGIN_URL ) ) .codeResolveUrl( config.readSettingAsString( PwmSetting.OAUTH_ID_CODERESOLVE_URL ) ) .attributesUrl( config.readSettingAsString( PwmSetting.OAUTH_ID_ATTRIBUTES_URL ) ) + .attributesMethod( config.readSettingAsHttpMethod( PwmSetting.OAUTH_ID_ATTRIBUTES_METHOD ) ) .clientID( config.readSettingAsString( PwmSetting.OAUTH_ID_CLIENTNAME ) ) .secret( config.readSettingAsPassword( PwmSetting.OAUTH_ID_SECRET ) ) .dnAttributeName( config.readSettingAsString( PwmSetting.OAUTH_ID_DN_ATTRIBUTE_NAME ) ) diff --git a/server/src/main/resources/password/pwm/config/PwmSetting.xml b/server/src/main/resources/password/pwm/config/PwmSetting.xml index bbc5074dfd..95758bd099 100644 --- a/server/src/main/resources/password/pwm/config/PwmSetting.xml +++ b/server/src/main/resources/password/pwm/config/PwmSetting.xml @@ -2471,6 +2471,15 @@ https://oauthserver.example.com/osp/a/idm/auth/oauth2/getattributes + +