CAS with OpenID Connect - How to set Redirect URI parameters using “?” instead of “#” after callback

1,099 views
Skip to first unread message

Kais Elouragini

unread,
Aug 16, 2017, 7:25:33 AM8/16/17
to CAS Community

Dear CAS Community,


I have CAS with OIDC installed and I have added a service as follows and it's working fine :

 {
        "implicit": true,
        "logoutType": "BACK_CHANNEL",
        "@class": "org.apereo.cas.services.OidcRegisteredService",
        "evaluationOrder": 1,
        "clientId": "TEST",
        "bypassApprovalPrompt": true,
        "jsonFormat": true,
        "jwks": "file:\/etc\/cas\/jwks\/\/enc-test-42.pub.jwks",
        "signIdToken": true,
        "description": "Test",
        "generateRefreshToken": true,
        "idTokenEncryptionEncoding": "A128GCM",
        "name": "Test client",
        "clientSecret": "TEST",
        "id": 42,
        "idTokenEncryptionAlg": "RSA-OAEP-256",
        "scopes": ["java.util.HashSet", ["openid", "profile", "email", "address", "phone"]],
        "serviceId": "https:\/\/redirect-host/callback",
        "encryptIdToken": true
    }

In order to login using CAS, I'm calling this URL :

http://cas-server/oidc/authorize?response_type=id_token+token&client_id=TEST&redirect_uri=https:\/\/redirect-host/callback&scope=openid+profile+email+phone+address

Login works fine but after being redirected from CAS to callback url, the accessToken is being appended to callback url with "#" not "?".

https://redirect-host/callback#accessToken=.....

Can I change "#" to "?" ? I need to have parameters with ? so that I can read them in the callback server. (using $_GET in PHP for example)


In CAS source code, I found that Redirect URL is being built in "OAuth20TokenAuthorizationResponseBuilder.java".


Kindly advise.


Thank you.

Jérôme LELEU

unread,
Aug 16, 2017, 7:32:22 AM8/16/17
to CAS Community
Hi,

The way you receive the access token depends on the OpenID Connect flow you choose. I recommend reading: https://connect2id.com/learn/openid-connect

In your case, "implicit: true" means the Javascript flow where the access token is passed in the URL after the #

Thanks.
Best regards,
Jérôme


--
- CAS gitter chatroom: https://gitter.im/apereo/cas
- CAS mailing list guidelines: https://apereo.github.io/cas/Mailing-Lists.html
- CAS documentation website: https://apereo.github.io/cas
- CAS project website: https://github.com/apereo/cas
---
You received this message because you are subscribed to the Google Groups "CAS Community" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cas-user+unsubscribe@apereo.org.
To view this discussion on the web visit https://groups.google.com/a/apereo.org/d/msgid/cas-user/213722c3-5308-46a6-9678-7d9acc671678%40apereo.org.

Kais Elouragini

unread,
Aug 16, 2017, 8:45:59 AM8/16/17
to CAS Community
Thank you so much Jérôme.

I've put implicit to false and realized that I should go with Authorization Flow as follows :
http://cas-server/oidc/authorize?response_type=code&client_id=TEST&redirect_uri=http://www.redirect-host/callback&scope=openid+profile+email+offline_access+phone+address

I'm getting redirected with the "code" parameter from CAS :
http://www.redirect-host/callback?code=OC-2-jUCPtzuPKHEJYq0B3KRwQ9YpDRCxQZsiQUO

I should now call the token endpoint with grant_type = authorization_code in order to get the access token and ID Token :
POST /oidc/accessToken HTTP/1.1
Host: http://cas-server
Content-Type: application/x-www-form-urlencoded
Authorization: Basic QUpNQU5fVFJBTlNQT1JUQVRJT046QUpNQU5fVFJBTlNQT1JUQVRJT04=
Cache-Control: no-cache
Postman-Token: 2e2bf169-deb4-c835-36ae-05216730987e

code=OC-2-jUCPtzuPKHEJYq0B3KRwQ9YpDRCxQZsiQUO&grant_type=authorization_code&redirect_uri=http://www.redirect-host/callback

By calling the above request, CAS is returning the following error :

{
    "timestamp": 1502887425667,
    "status": 500,
    "error": "Internal Server Error",
    "exception": "java.lang.IllegalArgumentException",
    "message": "ticket cannot be null",
    "trace": "java.lang.IllegalArgumentException: ticket cannot be null\n\tat org.springframework.util.Assert.notNull(Assert.java:134)\n\tat org.apereo.cas.ticket.registry.DefaultTicketRegistry.addTicket(DefaultTicketRegistry.java:57)\n\tat org.apereo.cas.ticket.registry.DefaultTicketRegistry.updateTicket(DefaultTicketRegistry.java:95)\n\tat org.apereo.cas.support.oauth.web.endpoints.BaseOAuth20Controller.generateAccessToken(BaseOAuth20Controller.java:132)\n\tat org.apereo.cas.support.oauth.web.endpoints.OAuth20AccessTokenEndpointController.handleRequest(OAuth20AccessTokenEndpointController.java:120)\n\tat org.apereo.cas.oidc.web.controllers.OidcAccessTokenEndpointController.handleRequest(OidcAccessTokenEndpointController.java:56)\n\tat org.apereo.cas.oidc.web.controllers.OidcAccessTokenEndpointController$$FastClassBySpringCGLIB$$60cb7b7e.invoke(<generated>)\n\tat org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)\n\tat org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:738)\n\tat org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)\n\tat org.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:133)\n\tat org.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:121)\n\tat org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)\n\tat org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:673)\n\tat org.apereo.cas.oidc.web.controllers.OidcAccessTokenEndpointController$$EnhancerBySpringCGLIB$$8fa17989.handleRequest(<generated>)\n\tat sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\n\tat sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)\n\tat sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\n\tat java.lang.reflect.Method.invoke(Method.java:498)\n\tat org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)\n\tat org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:133)\n\tat org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:97)\n\tat org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827)\n\tat org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738)\n\tat org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)\n\tat org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963)\n\tat org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897)\n\tat org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)\n\tat org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872)\n\tat javax.servlet.http.HttpServlet.service(HttpServlet.java:648)\n\tat org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)\n\tat javax.servlet.http.HttpServlet.service(HttpServlet.java:729)\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:292)\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)\n\tat org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)\n\tat org.apereo.cas.web.support.AuthenticationCredentialsLocalBinderClearingFilter.doFilter(AuthenticationCredentialsLocalBinderClearingFilter.java:28)\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)\n\tat org.apereo.cas.security.RequestParameterPolicyEnforcementFilter.doFilter(RequestParameterPolicyEnforcementFilter.java:261)\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)\n\tat org.apereo.cas.security.ResponseHeadersEnforcementFilter.doFilter(ResponseHeadersEnforcementFilter.java:238)\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)\n\tat org.springframework.boot.actuate.trace.WebRequestTraceFilter.doFilterInternal(WebRequestTraceFilter.java:110)\n\tat org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)\n\tat org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)\n\tat org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)\n\tat org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:105)\n\tat org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)\n\tat org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81)\n\tat org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)\n\tat org.apereo.cas.logging.web.ThreadContextMDCServletFilter.doFilter(ThreadContextMDCServletFilter.java:90)\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)\n\tat org.springframework.boot.actuate.autoconfigure.MetricsFilter.doFilterInternal(MetricsFilter.java:106)\n\tat org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)\n\tat org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197)\n\tat org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)\n\tat org.springframework.boot.web.support.ErrorPageFilter.doFilter(ErrorPageFilter.java:115)\n\tat org.springframework.boot.web.support.ErrorPageFilter.access$000(ErrorPageFilter.java:59)\n\tat org.springframework.boot.web.support.ErrorPageFilter$1.doFilterInternal(ErrorPageFilter.java:90)\n\tat org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)\n\tat org.springframework.boot.web.support.ErrorPageFilter.doFilter(ErrorPageFilter.java:108)\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)\n\tat org.apereo.inspektr.common.web.ClientInfoThreadLocalFilter.doFilter(ClientInfoThreadLocalFilter.java:64)\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)\n\tat org.apache.logging.log4j.web.Log4jServletFilter.doFilter(Log4jServletFilter.java:71)\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)\n\tat org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212)\n\tat org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:94)\n\tat org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:504)\n\tat org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141)\n\tat org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)\n\tat org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:620)\n\tat org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)\n\tat org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:502)\n\tat org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1132)\n\tat org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:684)\n\tat org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1533)\n\tat org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1489)\n\tat java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)\n\tat java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)\n\tat org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)\n\tat java.lang.Thread.run(Thread.java:748)\n",
    "path": "/oidc/accessToken"
}


When retrying with the same request, I'm getting "error=invalid_grant".

Any idea about that?

Thank you so much again for your support.



Priit Serk

unread,
Sep 11, 2017, 2:30:31 PM9/11/17
to CAS Community, kais.el...@gmail.com
Hi Kais

trying to get in touch regarding this CAS issue you posted while ago. I wrote a long letter but seems google didnt send it, so next try :)
Anyway, I cant get working oidc part of the cas and seems you were successful. Is there any way I could get in touch with you to consult for couple of minutes of how you actually achieved it. I'm seeing very strange behaviour of CAS.

I could give you a call or just describe the setup in our dev. environment. 

Br
skype: priit.serk
Reply all
Reply to author
Forward
0 new messages