I’m testing wso2 Identity server with an external OpenID Connect IDP. The external IDP is GLUU.
In my test case, I have three components:
- a simple web app deployed on localhost:8099
- a wso2 Identity Server deployed on localhost:9443 (with its default ports)
- a GLUU server deployed on localhost (with its default ports)
The flow I want to obtain is an OpenId Connect authorization_code, my "simple web app" (configured like a Service Provider in wso2is) requires a code to wso2is, are redirected to a GLUU login page, get the authorization code and exchanges the authorization code for an access token.
The "simple web app" is registered as a Service Provider in wso2is (with the name "Service Provider Test") with an inbound authentication configuration of type "OAuth/OpenId Connect Configuration." In this configuration I have set the callback URL of my "simple web app," and the client secret and client id used by my simple web app to obtain the access token.
This "Service Provider Test" in the section "Local & Outbound Authentication Configuration" is set to Federated Authentication, with "My Gluu Test IDP."
My Gluu Test IDP is the name of an Identity Provider I have added to wso2is's "service providers." I have uploaded the Gluu's certificate to "My Gluu Test IDP."
In the section "Federated Authenticators" of "My Gluu Test IDP" I have set up an "OAuth/OpenId Connect Configuration" with the information of the GLUU IDP (client id, secret, token and auth endpoints) and with this URL callback: https://localhost:9443/commonauth
This was the premise.
I try this scenario the first time and this is was I get:
- Calling wso2is authorization endpoint from my "simple web app"
- Redirect to GLUU login page
- Back to my "simple web app" callback uri with an error instead of the authorization code: {error_description=Authentication required, state=OX86oF, error=login_required, session_state=70b94648800ea5fa1e2476570ee9678225eaccc4deecea18ca9db022b7e1697c.fF2IdhJSG3aTE_TIsyGlYg}
The wso2is log related to this error is:
TID: [-1234] [] [2018-09-21 10:33:10,529] ERROR {org.wso2.carbon.identity.application.authentication.framework.handler.step.impl.DefaultStepHandler} - invalid_client, Client authentication failed (e.g. unknown client, no client authentication included, or unsupported authentication method). The authorization server MAY return an HTTP 401 (Unauthorized) status code to indicate which HTTP authentication schemes are supported. If the client attempted to authenticate via the Authorization request header field, the authorization server MUST respond with an HTTP 401 (Unauthorized) status code and include the WWW-Authenticate response header field matching the authentication scheme used by the client. org.wso2.carbon.identity.application.authentication.framework.exception.AuthenticationFailedException: invalid_client, Client authentication failed (e.g. unknown client, no client authentication included, or unsupported authentication method). The authorization server MAY return an HTTP 401 (Unauthorized) status code to indicate which HTTP authentication schemes are supported. If the client attempted to authenticate via the Authorization request header field, the authorization server MUST respond with an HTTP 401 (Unauthorized) status code and include the WWW-Authenticate response header field matching the authentication scheme used by the client. at org.wso2.carbon.identity.application.authenticator.oidc.OpenIDConnectAuthenticator.getOauthResponse(OpenIDConnectAuthenticator.java:585) at org.wso2.carbon.identity.application.authenticator.oidc.OpenIDConnectAuthenticator.processAuthenticationResponse(OpenIDConnectAuthenticator.java:370) at org.wso2.carbon.identity.application.authentication.framework.AbstractApplicationAuthenticator.process(AbstractApplicationAuthenticator.java:72) at org.wso2.carbon.identity.application.authentication.framework.handler.step.impl.DefaultStepHandler.doAuthentication(DefaultStepHandler.java:488) at org.wso2.carbon.identity.application.authentication.framework.handler.step.impl.DefaultStepHandler.handleResponse(DefaultStepHandler.java:462) at org.wso2.carbon.identity.application.authentication.framework.handler.step.impl.DefaultStepHandler.handle(DefaultStepHandler.java:165) at org.wso2.carbon.identity.application.authentication.framework.handler.sequence.impl.DefaultStepBasedSequenceHandler.handle(DefaultStepBasedSequenceHandler.java:176) at org.wso2.carbon.identity.application.authentication.framework.handler.sequence.impl.GraphBasedSequenceHandler.handle(GraphBasedSequenceHandler.java:63) at org.wso2.carbon.identity.application.authentication.framework.handler.request.impl.DefaultAuthenticationRequestHandler.handle(DefaultAuthenticationRequestHandler.java:131) at org.wso2.carbon.identity.application.authentication.framework.handler.request.impl.DefaultRequestCoordinator.handle(DefaultRequestCoordinator.java:157) at org.wso2.carbon.identity.application.authentication.framework.servlet.CommonAuthenticationServlet.doPost(CommonAuthenticationServlet.java:53) at org.wso2.carbon.identity.application.authentication.framework.servlet.CommonAuthenticationServlet.doGet(CommonAuthenticationServlet.java:43) at javax.servlet.http.HttpServlet.service(HttpServlet.java:624) at javax.servlet.http.HttpServlet.service(HttpServlet.java:731) at org.eclipse.equinox.http.helper.ContextPathServletAdaptor.service(ContextPathServletAdaptor.java:37) at org.eclipse.equinox.http.servlet.internal.ServletRegistration.service(ServletRegistration.java:61) at org.eclipse.equinox.http.servlet.internal.ProxyServlet.processAlias(ProxyServlet.java:128) at org.eclipse.equinox.http.servlet.internal.ProxyServlet.service(ProxyServlet.java:60) at javax.servlet.http.HttpServlet.service(HttpServlet.java:731) at org.wso2.carbon.tomcat.ext.servlet.DelegationServlet.service(DelegationServlet.java:68) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) at org.wso2.carbon.identity.captcha.filter.CaptchaFilter.doFilter(CaptchaFilter.java:76) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) at org.owasp.csrfguard.CsrfGuardFilter.doFilter(CsrfGuardFilter.java:72) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) at org.wso2.carbon.tomcat.ext.filter.CharacterSetFilter.doFilter(CharacterSetFilter.java:65) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) at org.apache.catalina.filters.HttpHeaderSecurityFilter.doFilter(HttpHeaderSecurityFilter.java:124) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:110) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:169) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103) at org.wso2.carbon.identity.context.rewrite.valve.TenantContextRewriteValve.invoke(TenantContextRewriteValve.java:80) at org.wso2.carbon.identity.authz.valve.AuthorizationValve.invoke(AuthorizationValve.java:91) at org.wso2.carbon.identity.auth.valve.AuthenticationValve.invoke(AuthenticationValve.java:60) at org.wso2.carbon.tomcat.ext.valves.CompositeValve.continueInvocation(CompositeValve.java:99) at org.wso2.carbon.tomcat.ext.valves.CarbonTomcatValve$1.invoke(CarbonTomcatValve.java:47) at org.wso2.carbon.webapp.mgt.TenantLazyLoaderValve.invoke(TenantLazyLoaderValve.java:57) at org.wso2.carbon.tomcat.ext.valves.TomcatValveContainer.invokeValves(TomcatValveContainer.java:47) at org.wso2.carbon.tomcat.ext.valves.CompositeValve.invoke(CompositeValve.java:62) at org.wso2.carbon.tomcat.ext.valves.CarbonStuckThreadDetectionValve.invoke(CarbonStuckThreadDetectionValve.java:159) at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:962) at org.wso2.carbon.tomcat.ext.valves.CarbonContextCreatorValve.invoke(CarbonContextCreatorValve.java:57) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:445) at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1115) at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:637) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1775) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1734) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.lang.Thread.run(Thread.java:748) Caused by: OAuthProblemException{error='invalid_client', description='Client authentication failed (e.g. unknown client, no client authentication included, or unsupported authentication method). The authorization server MAY return an HTTP 401 (Unauthorized) status code to indicate which HTTP authentication schemes are supported. If the client attempted to authenticate via the Authorization request header field, the authorization server MUST respond with an HTTP 401 (Unauthorized) status code, and include the WWW-Authenticate response header field matching the authentication scheme used by the client.', uri='null', state='null', scope='null', redirectUri='null', responseStatus=0, parameters={}} at org.apache.oltu.oauth2.common.exception.OAuthProblemException.error(OAuthProblemException.java:59) at org.apache.oltu.oauth2.client.validator.OAuthClientValidator.validateErrorResponse(OAuthClientValidator.java:63) at org.apache.oltu.oauth2.client.validator.OAuthClientValidator.validate(OAuthClientValidator.java:48) at org.apache.oltu.oauth2.client.response.OAuthClientResponse.validate(OAuthClientResponse.java:64) at org.apache.oltu.oauth2.client.response.OAuthClientResponse.init(OAuthClientResponse.java:59) at org.apache.oltu.oauth2.client.response.OAuthAccessTokenResponse.init(OAuthAccessTokenResponse.java:52) at org.apache.oltu.oauth2.client.response.OAuthClientResponseFactory.createCustomResponse(OAuthClientResponseFactory.java:60) at org.apache.oltu.oauth2.client.URLConnectionClient.execute(URLConnectionClient.java:111) at org.apache.oltu.oauth2.client.OAuthClient.accessToken(OAuthClient.java:65) at org.apache.oltu.oauth2.client.OAuthClient.accessToken(OAuthClient.java:55) at org.apache.oltu.oauth2.client.OAuthClient.accessToken(OAuthClient.java:71) at org.wso2.carbon.identity.application.authenticator.oidc.OpenIDConnectAuthenticator.getOauthResponse(OpenIDConnectAuthenticator.java:580) ... 61 more
After this error, with the GLUU administration UI, I changed the "authentication method for token endpoint" from client_secret_basic to client_secret_post, and I tried the test again, and all works fine:
- Calling wso2is authorization endpoint from my "simple web app."
- Redirect to GLUU login page
- Redirect to WSO2IS auth page (OpenID User Claims Service Provider Test application requests access to your profile information ...)
- Back to my "simple web app" callback uri with the authorization code: {code=7269a75f-8702-3843-a553-465b69546a27, state=6yFD89, session_state=61d504abd9fe3cda28934f4aa394b156d6792071669f3020d4b79373ba5a1236.-QhpECv8pyocY1T2uu-kBQ}
- My "simple web app" calls the wso2is authorization endpoint, passing the code, and obtain the accecc_token
And finally my question:
In this test scenario I can change the configurations of the external IDP, but in a real-world scenario, I could not change that parameter on the external IDP. I could not find in the WSO2IS Identity Provider configuration how to choose from client_secret_basic, client_secret_post, client_secret_jwt, private_key_jwt, none.
Without changing the GLUU IDP setting from client_secret_basic to client_secret_post what should I change in the wso2is's configuration to make this scenario work?
From IS 5.6.0 onwards, you have the option to configure the client authentication mechanism. In the 'OAuth2/OpenID Connect Configuration' of the IdP settings, you can use the 'Enable HTTP basic auth for client authentication' property to achieve your requirement.