Infrequent NoSuchEJBException: EJB has been removed after session timeout, browser refresh - jsf-2

I have a facelet that refreshes the browser window 30 seconds after session timeout e.g.
<a4j:region>
<h:form>
<a4j:poll id="poll" interval="#{(session.maxInactiveInterval + 30)*1000}" onbegin="window.document.location.href='/Patrac'"/>
</h:form>
</a4j:region>
The facelet, when reloaded, causes a method to be invoked on a SFSB e.g.
<ui:define name="title">PATRAC - #{workflowManager.currentWorkflow.screenTitle}</ui:define>
The SFSB is session scoped.
#SessionScoped
#Stateful
public class WorkflowManager {
...
public Workflow getCurrentWorkflow() { return currentWorkflow; }
#PreDestroy public void bye() { System.out.println("Destroying: "+ getClass().getName() +", ID = "+ getId()); }
}
85 percent of the time the screen is refreshed without incident:
15:56:44,951 INFO [stdout] (http-/127.0.0.1:8443-1) Destroying: com.patrac.controller.statemachine.WorkflowManager, ID = -1906221148858801782
15:56:44,968 INFO [com.patrac.filter.NoCacheFilter] (http-/127.0.0.1:8443-1) NoCacheFilter.doFilter() URI: /Patrac/
15:58:01,343 INFO [stdout] (ContainerBackgroundProcessor[StandardEngine[jboss.web]]) Destroying: com.patrac.controller.statemachine.WorkflowManager, ID = -3546919396833964128
15:58:15,288 INFO [com.patrac.filter.NoCacheFilter] (http-/127.0.0.1:8443-3) NoCacheFilter.doFilter() URI: /Patrac/index.xhtml
15:58:15,319 INFO [com.patrac.filter.NoCacheFilter] (http-/127.0.0.1:8443-4) NoCacheFilter.doFilter() URI: /Patrac/
15:58:15,349 WARNING [com.patrac.controller.exceptionhandler.ViewExpiredExceptionHandler] (http-/127.0.0.1:8443-3) Attempt to access an expired view: /index.xhtml from remote host: 127.0.0.1
15:58:15,389 INFO [com.patrac.filter.NoCacheFilter] (http-/127.0.0.1:8443-4) NoCacheFilter.doFilter() URI: /Patrac/index.xhtml
15:59:45,771 INFO [stdout] (http-/127.0.0.1:8443-1) Destroying: com.patrac.controller.statemachine.WorkflowManager, ID = -5655846827584878649
15:59:45,777 INFO [com.patrac.filter.NoCacheFilter] (http-/127.0.0.1:8443-1) NoCacheFilter.doFilter() URI: /Patrac/index.xhtml
15:59:45,800 WARNING [com.patrac.controller.exceptionhandler.ViewExpiredExceptionHandler] (http-/127.0.0.1:8443-1) Attempt to access an expired view: /index.xhtml from remote host: 127.0.0.1
15:59:45,890 INFO [com.patrac.filter.NoCacheFilter] (http-/127.0.0.1:8443-1) NoCacheFilter.doFilter() URI: /Patrac/index.xhtml
16:00:01,356 INFO [stdout] (ContainerBackgroundProcessor[StandardEngine[jboss.web]]) Destroying: com.patrac.controller.statemachine.WorkflowManager, ID = 4579100734353654546
16:01:01,363 INFO [stdout] (ContainerBackgroundProcessor[StandardEngine[jboss.web]]) Destroying: com.patrac.controller.statemachine.WorkflowManager, ID = 4317425328092070112
16:01:16,518 INFO [com.patrac.filter.NoCacheFilter] (http-/127.0.0.1:8443-3) NoCacheFilter.doFilter() URI: /Patrac/index.xhtml
16:01:16,526 INFO [com.patrac.filter.NoCacheFilter] (http-/127.0.0.1:8443-8) NoCacheFilter.doFilter() URI: /Patrac/
16:01:16,544 WARNING [com.patrac.controller.exceptionhandler.ViewExpiredExceptionHandler] (http-/127.0.0.1:8443-3) Attempt to access an expired view: /index.xhtml from remote host: 127.0.0.1
16:01:16,572 INFO [com.patrac.filter.NoCacheFilter] (http-/127.0.0.1:8443-3) NoCacheFilter.doFilter() URI: /Patrac/index.xhtml
16:02:46,894 INFO [stdout] (http-/127.0.0.1:8443-1) Destroying: com.patrac.controller.statemachine.WorkflowManager, ID = 7360031599060690367
16:02:46,900 INFO [com.patrac.filter.NoCacheFilter] (http-/127.0.0.1:8443-1) NoCacheFilter.doFilter() URI: /Patrac/index.xhtml
16:02:46,923 INFO [com.patrac.filter.NoCacheFilter] (http-/127.0.0.1:8443-6) NoCacheFilter.doFilter() URI: /Patrac/
16:02:46,950 WARNING [com.patrac.controller.exceptionhandler.ViewExpiredExceptionHandler] (http-/127.0.0.1:8443-1) Attempt to access an expired view: /index.xhtml from remote host: 127.0.0.1
16:02:46,975 INFO [com.patrac.filter.NoCacheFilter] (http-/127.0.0.1:8443-1) NoCacheFilter.doFilter() URI: /Patrac/index.xhtml
16:03:01,380 INFO [stdout] (ContainerBackgroundProcessor[StandardEngine[jboss.web]]) Destroying: com.patrac.controller.statemachine.WorkflowManager, ID = -5741388414554084710
16:04:01,389 INFO [stdout] (ContainerBackgroundProcessor[StandardEngine[jboss.web]]) Destroying: com.patrac.controller.statemachine.WorkflowManager, ID = -1149102875316717372
16:04:01,395 INFO [stdout] (ContainerBackgroundProcessor[StandardEngine[jboss.web]]) Destroying: com.patrac.controller.statemachine.WorkflowManager, ID = -7198492156368620025
16:04:17,355 INFO [com.patrac.filter.NoCacheFilter] (http-/127.0.0.1:8443-7) NoCacheFilter.doFilter() URI: /Patrac/index.xhtml
16:04:17,365 INFO [com.patrac.filter.NoCacheFilter] (http-/127.0.0.1:8443-8) NoCacheFilter.doFilter() URI: /Patrac/
16:04:17,405 WARNING [com.patrac.controller.exceptionhandler.ViewExpiredExceptionHandler] (http-/127.0.0.1:8443-7) Attempt to access an expired view: /index.xhtml from remote host: 127.0.0.1
16:04:17,460 INFO [com.patrac.filter.NoCacheFilter] (http-/127.0.0.1:8443-8) NoCacheFilter.doFilter() URI: /Patrac/index.xhtml
16:05:47,769 INFO [stdout] (http-/127.0.0.1:8443-7) Destroying: com.patrac.controller.statemachine.WorkflowManager, ID = -8106288024707282506
16:05:47,773 INFO [com.patrac.filter.NoCacheFilter] (http-/127.0.0.1:8443-7) NoCacheFilter.doFilter() URI: /Patrac/index.xhtml
16:05:47,808 INFO [com.patrac.filter.NoCacheFilter] (http-/127.0.0.1:8443-6) NoCacheFilter.doFilter() URI: /Patrac/
16:05:47,809 WARNING [com.patrac.controller.exceptionhandler.ViewExpiredExceptionHandler] (http-/127.0.0.1:8443-7) Attempt to access an expired view: /index.xhtml from remote host: 127.0.0.1
16:05:47,856 INFO [com.patrac.filter.NoCacheFilter] (http-/127.0.0.1:8443-7) NoCacheFilter.doFilter() URI: /Patrac/index.xhtml
16:06:01,409 INFO [stdout] (ContainerBackgroundProcessor[StandardEngine[jboss.web]]) Destroying: com.patrac.controller.statemachine.WorkflowManager, ID = 6737131848251158629
16:07:01,419 INFO [stdout] (ContainerBackgroundProcessor[StandardEngine[jboss.web]]) Destroying: com.patrac.controller.statemachine.WorkflowManager, ID = -3248726216386741006
16:07:01,423 INFO [stdout] (ContainerBackgroundProcessor[StandardEngine[jboss.web]]) Destroying: com.patrac.controller.statemachine.WorkflowManager, ID = -7798326820709515585
16:07:18,188 INFO [com.patrac.filter.NoCacheFilter] (http-/127.0.0.1:8443-8) NoCacheFilter.doFilter() URI: /Patrac/
16:07:18,188 INFO [com.patrac.filter.NoCacheFilter] (http-/127.0.0.1:8443-1) NoCacheFilter.doFilter() URI: /Patrac/index.xhtml
16:07:18,219 WARNING [com.patrac.controller.exceptionhandler.ViewExpiredExceptionHandler] (http-/127.0.0.1:8443-1) Attempt to access an expired view: /index.xhtml from remote host: 127.0.0.1
16:07:18,250 INFO [com.patrac.filter.NoCacheFilter] (http-/127.0.0.1:8443-1) NoCacheFilter.doFilter() URI: /Patrac/index.xhtml
However, sometimes the following happens:
16:08:48,536 INFO [stdout] (http-/127.0.0.1:8443-7) Destroying: com.patrac.controller.statemachine.WorkflowManager, ID = 601708170643229812
16:08:48,537 INFO [com.patrac.filter.NoCacheFilter] (http-/127.0.0.1:8443-7) NoCacheFilter.doFilter() URI: /Patrac/index.xhtml
16:08:48,540 ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[default-host]] (http-/127.0.0.1:8443-3) Exception sending request initialized lifecycle event to listener instance of class org.jboss.weld.servlet.WeldListener: javax.ejb.NoSuchEJBException: JBAS016055: EJB has been removed
at org.jboss.as.weld.ejb.StatefulSessionObjectReferenceImpl.getBusinessObject(StatefulSessionObjectReferenceImpl.java:124) [jboss-as-weld-7.2.0.Alpha1-SNAPSHOT.jar:7.2.0.Alpha1-SNAPSHOT]
at org.jboss.weld.bean.proxy.EnterpriseBeanProxyMethodHandler.invoke(EnterpriseBeanProxyMethodHandler.java:108) [weld-core-1.1.9.Final.jar:2012-08-06 19:12]
at org.jboss.weld.bean.proxy.EnterpriseTargetBeanInstance.invoke(EnterpriseTargetBeanInstance.java:56) [weld-core-1.1.9.Final.jar:2012-08-06 19:12]
at org.jboss.weld.bean.proxy.ProxyMethodHandler.invoke(ProxyMethodHandler.java:105) [weld-core-1.1.9.Final.jar:2012-08-06 19:12]
at com.patrac.controller.statemachine.WorkflowManager$Proxy$_$$_Weld$Proxy$.toString(WorkflowManager$Proxy$_$$_Weld$Proxy$.java) [Patrac-ejb.jar:]
at java.lang.String.valueOf(String.java:2854) [rt.jar:1.7.0_07]
at java.lang.StringBuilder.append(StringBuilder.java:128) [rt.jar:1.7.0_07]
at org.jboss.weld.context.SerializableContextualInstanceImpl.toString(SerializableContextualInstanceImpl.java:60) [weld-core-1.1.9.Final.jar:2012-08-06 19:12]
at java.lang.String.valueOf(String.java:2854) [rt.jar:1.7.0_07]
at java.lang.StringBuilder.append(StringBuilder.java:128) [rt.jar:1.7.0_07]
at org.jboss.weld.context.beanstore.AttributeBeanStore.attach(AttributeBeanStore.java:109) [weld-core-1.1.9.Final.jar:2012-08-06 19:12]
at org.jboss.weld.context.AbstractBoundContext.activate(AbstractBoundContext.java:66) [weld-core-1.1.9.Final.jar:2012-08-06 19:12]
at org.jboss.weld.servlet.WeldListener.requestInitialized(WeldListener.java:141) [weld-core-1.1.9.Final.jar:2012-08-06 19:12]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143) [jbossweb-7.0.17.Final.jar:]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) [jbossweb-7.0.17.Final.jar:]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) [jbossweb-7.0.17.Final.jar:]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:372) [jbossweb-7.0.17.Final.jar:]
at org.apache.coyote.http11.Http11AprProcessor.process(Http11AprProcessor.java:897) [jbossweb-7.0.17.Final.jar:]
at org.apache.coyote.http11.Http11AprProtocol$Http11ConnectionHandler.process(Http11AprProtocol.java:634) [jbossweb-7.0.17.Final.jar:]
at org.apache.tomcat.util.net.AprEndpoint$Worker.run(AprEndpoint.java:2039) [jbossweb-7.0.17.Final.jar:]
at java.lang.Thread.run(Thread.java:722) [rt.jar:1.7.0_07]
16:08:48,561 WARNING [com.patrac.controller.exceptionhandler.ViewExpiredExceptionHandler] (http-/127.0.0.1:8443-7) Attempt to access an expired view: /index.xhtml from remote host: 127.0.0.1
The stack trace always appears in the browser window, so this happens after the browser makes a request when the session is timed out. It only happens when the request is received at nearly the same time that the SFSB is destroyed (within milliseconds). It never happens upon logout, although the 302 REDIRECT causes the brower to make a request only milliseconds after the SFSB is destroyed. It seems to be that not only is timing a factor but also a ViewExpiredException is thrown every time this happens.
It seems as though what's happening is that because the session times out but the EJB is not immediately removed, when the browser makes a request JBoss removes the EJB from the timed out session and then throws the exception that the EJB has been removed instead of first creating a new EJB and binding it to the new session.
How can I handle the NoSuchEJBException, or better yet to avoid it altogether?

The problem was solved by making the ViewExpiredExceptionHandler redirect to a facelet, viewExpired.xhtml.
Prior to this change, ViewExpiredExceptionHandler was redirecting to the root of the web app, /Patrac, and the following entry in web.xml was causing another redirect to index.xhtml:
<welcome-file-list>
<welcome-file>index.xhtml</welcome-file>
</welcome-file-list>
Moreover, index.xhtml was configured to refresh to /Patrac, which would be redirected to /Patrac/index.xhtml, which would result in a ViewExpiredException, which would result in another redirect /Patrac, which would redirect to the welcome page, /Patrac/index.xhtml, all in rapid succession.
<a4j:poll id="poll" interval="#{(session.maxInactiveInterval + 30)*1000}" onbegin="window.document.location.href='/Patrac'"/>
Usually, there was no problem. But per the Servlet spec., sessions aren't necessarily destroyed exactly at the time specified in the deployment descriptor -- there is some variation. So, occasionally when when the browser refresh occurred within several milliseconds of the session being destroyed on the server side and JBoss hadn't finished cleaning up its state the NoSuchEJBExceptions were being thrown.
Changing the client side ajax poll/timeout in index.xhtml to the following and making sure that viewExpiredException.xhtml did not do any browser refresh/ ajax polling made the problem go away.
<a4j:poll id="poll" interval="#{(session.maxInactiveInterval + 30)*1000}" onbegin="window.document.location.href='/Patrac/viewExpired.xhtml"/>

Try to use StatefulTimeout
#StatefulTimeout(unit = TimeUnit.MINUTES, value = 30)

Related

Spring Authorization Server 1.0 sample federated-identity-authorizationserver gives invalid_token_response

I am trying out federated-identity-authorizationserver sample given in sample.
I updated the yml files as required.
I was able to start auth server and resource server.
While starting client I got provider issuer error which I resolved by updating client yml as below
provider:
spring:
authorization-uri: http://localhost:9000/oauth2/authorize
token-uri: http://localhost:9000/oauth2/token
#issuer-uri: http://localhost:9000
I am able to start the messaging client and able to perform authentication with google but getting below error. I am getting same error if I try it with local auth server using user1/password credentials.
{"exception":"[invalid_token_response] An error occurred while attempting to retrieve the OAuth 2.0 Access Token Response: Could not extract response: no suitable HttpMessageConverter found for response type [class org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse] and content type [text/html;charset=utf-8]","timestamp":1674192821362}
To get the error I added failureHandler as below otherwise I was getting too many redirects error.
#Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(authorize ->
authorize.anyRequest().authenticated()
)
.oauth2Login(oauth2Login ->
oauth2Login.loginPage("/oauth2/authorization/messaging-client-oidc").successHandler(new LoginSuccessHandler()).failureHandler(new CustomAuthenticationFailureHandler()))
.oauth2Client(withDefaults());
return http.build();
I also tried adding accessTokenResponseClient as below but error remains same and the accessTokenResponseClient to the client config but it is not getting invoked. I have authorizationCodeTokenResponseClient() and other relevant classes.
.oauth2Login(oauth2Login ->
oauth2Login
.tokenEndpoint(tokenEndpoint ->
tokenEndpoint
.accessTokenResponseClient(authorizationCodeTokenResponseClient()))
.loginPage("/oauth2/authorization/messaging-client-oidc").successHandler(new LoginSuccessHandler()).failureHandler(new CustomAuthenticationFailureHandler()))
.oauth2Client(withDefaults());
I am getting above error when I try with local auth server and Google as a federated auth server.
The debug trace from client just before the error. the code is matching the federated server code
2023-01-24T22:24:59.078+05:30 DEBUG 96239 --- [nio-8080-exec-5] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler [classpath [META-INF/resources/], classpath [resources/], classpath [static/], classpath [public/], ServletContext [/]]
2023-01-24T22:24:59.079+05:30 DEBUG 96239 --- [nio-8080-exec-5] o.s.security.web.FilterChainProxy : Securing GET /login/oauth2/code/messaging-client-oidc?code=DxWgpwZqmepYInMZ0lBZrboaEVULZYep8r2I9Kz6MM9rY-2O2Bg1wSMiKPhwMM2U2Uf9bvd2N9pMFXbB7mCKw4GlDULdgNSADjHOzXQxdEGRNPtRVBU7i6OKfkxCtB7i&state=2gTNT52oxL3kRqtnbA0vnXQzp3VrghJmLtVUNEtagRo%3D
2023-01-24T22:24:59.092+05:30 DEBUG 96239 --- [nio-8080-exec-5] o.s.web.client.RestTemplate : HTTP POST http://localhost:9000/oauth2/token
2023-01-24T22:24:59.095+05:30 DEBUG 96239 --- [nio-8080-exec-5] o.s.web.client.RestTemplate : Accept=[application/json, application/*+json]
2023-01-24T22:24:59.096+05:30 DEBUG 96239 --- [nio-8080-exec-5] o.s.web.client.RestTemplate : Writing [{grant_type=[authorization_code], code=[DxWgpwZqmepYInMZ0lBZrboaEVULZYep8r2I9Kz6MM9rY-2O2Bg1wSMiKPhwMM2U2Uf9bvd2N9pMFXbB7mCKw4GlDULdgNSADjHOzXQxdEGRNPtRVBU7i6OKfkxCtB7i], redirect_uri=[http://127.0.0.1:8080/login/oauth2/code/messaging-client-oidc]}] as "application/x-www-form-urlencoded;charset=UTF-8"
2023-01-24T22:24:59.276+05:30 DEBUG 96239 --- [nio-8080-exec-5] o.s.web.client.RestTemplate : Response 200 OK
2023-01-24T22:24:59.284+05:30 DEBUG 96239 --- [nio-8080-exec-5] .s.a.DefaultAuthenticationEventPublisher : No event was found for the exception org.springframework.security.oauth2.core.OAuth2AuthenticationException
org.springframework.security.oauth2.core.OAuth2AuthenticationException: [invalid_token_response] An error occurred while attempting to retrieve the OAuth 2.0 Access Token Response: Could not extract response: no suitable HttpMessageConverter found for response type [class org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse] and content type [text/html;charset=utf-8]
at org.springframework.security.oauth2.client.oidc.authentication.OidcAuthorizationCodeAuthenticationProvider.getResponse(OidcAuthorizationCodeAuthenticationProvider.java:176) ~[spring-security-oauth2-client-6.0.0.jar:6.0.0]
at org.springframework.security.oauth2.client.oidc.authentication.OidcAuthorizationCodeAuthenticationProvider.authenticate(OidcAuthorizationCodeAuthenticationProvider.java:144) ~[spring-security-oauth2-client-6.0.0.jar:6.0.0]
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:182) ~[spring-security-core-6.0.0.jar:6.0.0]
at org.springframework.security.oauth2.client.web.OAuth2LoginAuthenticationFilter.attemptAuthentication(OAuth2LoginAuthenticationFilter.java:195) ~[spring-security-oauth2-client-6.0.0.jar:6.0.0]
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:231) ~[spring-security-web-6.0.0.jar:6.0.0]
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:221) ~[spring-security-web-6.0.0.jar:6.0.0]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) ~[spring-security-web-6.0.0.jar:6.0.0]
at org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestRedirectFilter.doFilterInternal(OAuth2AuthorizationRequestRedirectFilter.java:181) ~[spring-security-oauth2-client-6.0.0.jar:6.0.0]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.0.2.jar:6.0.2]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) ~[spring-security-web-6.0.0.jar:6.0.0]
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:107) ~[spring-security-web-6.0.0.jar:6.0.0]
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:93) ~[spring-security-web-6.0.0.jar:6.0.0]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) ~[spring-security-web-6.0.0.jar:6.0.0]
at org.springframework.security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.java:116) ~[spring-security-web-6.0.0.jar:6.0.0]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.0.2.jar:6.0.2]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) ~[spring-security-web-6.0.0.jar:6.0.0]
at org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:90) ~[spring-security-web-6.0.0.jar:6.0.0]
at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:75) ~[spring-security-web-6.0.0.jar:6.0.0]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.0.2.jar:6.0.2]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) ~[spring-security-web-6.0.0.jar:6.0.0]
at org.springframework.security.web.context.SecurityContextHolderFilter.doFilterInternal(SecurityContextHolderFilter.java:69) ~[spring-security-web-6.0.0.jar:6.0.0]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.0.2.jar:6.0.2]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) ~[spring-security-web-6.0.0.jar:6.0.0]
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:62) ~[spring-security-web-6.0.0.jar:6.0.0]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.0.2.jar:6.0.2]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) ~[spring-security-web-6.0.0.jar:6.0.0]
at org.springframework.security.web.session.DisableEncodeUrlFilter.doFilterInternal(DisableEncodeUrlFilter.java:42) ~[spring-security-web-6.0.0.jar:6.0.0]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.0.2.jar:6.0.2]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) ~[spring-security-web-6.0.0.jar:6.0.0]
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:233) ~[spring-security-web-6.0.0.jar:6.0.0]
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:191) ~[spring-security-web-6.0.0.jar:6.0.0]
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:351) ~[spring-web-6.0.2.jar:6.0.2]
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:267) ~[spring-web-6.0.2.jar:6.0.2]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:185) ~[tomcat-embed-core-10.1.1.jar:10.1.1]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:158) ~[tomcat-embed-core-10.1.1.jar:10.1.1]
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-6.0.2.jar:6.0.2]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.0.2.jar:6.0.2]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:185) ~[tomcat-embed-core-10.1.1.jar:10.1.1]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:158) ~[tomcat-embed-core-10.1.1.jar:10.1.1]
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-6.0.2.jar:6.0.2]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.0.2.jar:6.0.2]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:185) ~[tomcat-embed-core-10.1.1.jar:10.1.1]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:158) ~[tomcat-embed-core-10.1.1.jar:10.1.1]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-6.0.2.jar:6.0.2]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.0.2.jar:6.0.2]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:185) ~[tomcat-embed-core-10.1.1.jar:10.1.1]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:158) ~[tomcat-embed-core-10.1.1.jar:10.1.1]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197) ~[tomcat-embed-core-10.1.1.jar:10.1.1]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) ~[tomcat-embed-core-10.1.1.jar:10.1.1]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542) ~[tomcat-embed-core-10.1.1.jar:10.1.1]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:119) ~[tomcat-embed-core-10.1.1.jar:10.1.1]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[tomcat-embed-core-10.1.1.jar:10.1.1]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) ~[tomcat-embed-core-10.1.1.jar:10.1.1]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357) ~[tomcat-embed-core-10.1.1.jar:10.1.1]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:400) ~[tomcat-embed-core-10.1.1.jar:10.1.1]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-embed-core-10.1.1.jar:10.1.1]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:861) ~[tomcat-embed-core-10.1.1.jar:10.1.1]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1739) ~[tomcat-embed-core-10.1.1.jar:10.1.1]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) ~[tomcat-embed-core-10.1.1.jar:10.1.1]
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) ~[tomcat-embed-core-10.1.1.jar:10.1.1]
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-embed-core-10.1.1.jar:10.1.1]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-10.1.1.jar:10.1.1]
at java.base/java.lang.Thread.run(Thread.java:833) ~[na:na]
Caused by: org.springframework.security.oauth2.core.OAuth2AuthorizationException: [invalid_token_response] An error occurred while attempting to retrieve the OAuth 2.0 Access Token Response: Could not extract response: no suitable HttpMessageConverter found for response type [class org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse] and content type [text/html;charset=utf-8]
at org.springframework.security.oauth2.client.endpoint.DefaultAuthorizationCodeTokenResponseClient.getResponse(DefaultAuthorizationCodeTokenResponseClient.java:95) ~[spring-security-oauth2-client-6.0.0.jar:6.0.0]
at org.springframework.security.oauth2.client.endpoint.DefaultAuthorizationCodeTokenResponseClient.getTokenResponse(DefaultAuthorizationCodeTokenResponseClient.java:77) ~[spring-security-oauth2-client-6.0.0.jar:6.0.0]
at org.springframework.security.oauth2.client.endpoint.DefaultAuthorizationCodeTokenResponseClient.getTokenResponse(DefaultAuthorizationCodeTokenResponseClient.java:56) ~[spring-security-oauth2-client-6.0.0.jar:6.0.0]
at org.springframework.security.oauth2.client.oidc.authentication.OidcAuthorizationCodeAuthenticationProvider.getResponse(OidcAuthorizationCodeAuthenticationProvider.java:170) ~[spring-security-oauth2-client-6.0.0.jar:6.0.0]
... 62 common frames omitted
The debug trace from auth server
2023-01-24T22:24:54.510+05:30 INFO 96235 --- [nio-9000-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 2 ms
2023-01-24T22:24:54.518+05:30 DEBUG 96235 --- [nio-9000-exec-1] o.s.security.web.FilterChainProxy : Securing GET /oauth2/authorize?response_type=code&client_id=messaging-client&scope=openid%20profile&state=2gTNT52oxL3kRqtnbA0vnXQzp3VrghJmLtVUNEtagRo%3D&redirect_uri=http://127.0.0.1:8080/login/oauth2/code/messaging-client-oidc&nonce=FTOwMi9WPU3zHBPBrG2Jj-Dxm0udS_dLfI1I0TiN2Ws
2023-01-24T22:24:54.581+05:30 DEBUG 96235 --- [nio-9000-exec-1] o.s.s.w.a.AnonymousAuthenticationFilter : Set SecurityContextHolder to anonymous SecurityContext
2023-01-24T22:24:54.608+05:30 DEBUG 96235 --- [nio-9000-exec-1] o.s.s.w.s.HttpSessionRequestCache : Saved request http://localhost:9000/oauth2/authorize?response_type=code&client_id=messaging-client&scope=openid%20profile&state=2gTNT52oxL3kRqtnbA0vnXQzp3VrghJmLtVUNEtagRo%3D&redirect_uri=http://127.0.0.1:8080/login/oauth2/code/messaging-client-oidc&nonce=FTOwMi9WPU3zHBPBrG2Jj-Dxm0udS_dLfI1I0TiN2Ws&continue to session
2023-01-24T22:24:54.609+05:30 DEBUG 96235 --- [nio-9000-exec-1] o.s.s.web.DefaultRedirectStrategy : Redirecting to http://localhost:9000/login
2023-01-24T22:24:54.615+05:30 DEBUG 96235 --- [nio-9000-exec-2] o.s.security.web.FilterChainProxy : Securing GET /login
2023-01-24T22:24:54.625+05:30 DEBUG 96235 --- [nio-9000-exec-2] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to sample.web.LoginController#login()
2023-01-24T22:24:54.627+05:30 DEBUG 96235 --- [nio-9000-exec-2] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to sample.web.LoginController#login()
2023-01-24T22:24:54.627+05:30 DEBUG 96235 --- [nio-9000-exec-2] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to sample.web.LoginController#login()
2023-01-24T22:24:54.627+05:30 DEBUG 96235 --- [nio-9000-exec-2] o.s.security.web.FilterChainProxy : Secured GET /login
2023-01-24T22:24:54.630+05:30 DEBUG 96235 --- [nio-9000-exec-2] o.s.web.servlet.DispatcherServlet : GET "/login", parameters={}
2023-01-24T22:24:54.632+05:30 DEBUG 96235 --- [nio-9000-exec-2] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to sample.web.LoginController#login()
2023-01-24T22:24:54.647+05:30 DEBUG 96235 --- [nio-9000-exec-2] o.s.w.s.v.ContentNegotiatingViewResolver : Selected 'text/html' given [text/html, application/xhtml+xml, image/avif, image/webp, image/apng, application/xml;q=0.9, application/signed-exchange;v=b3;q=0.9, */*;q=0.8]
2023-01-24T22:24:54.889+05:30 DEBUG 96235 --- [nio-9000-exec-2] o.s.web.servlet.DispatcherServlet : Completed 200 OK
2023-01-24T22:24:54.889+05:30 DEBUG 96235 --- [nio-9000-exec-2] o.s.s.w.a.AnonymousAuthenticationFilter : Set SecurityContextHolder to anonymous SecurityContext
2023-01-24T22:24:56.340+05:30 DEBUG 96235 --- [nio-9000-exec-3] o.s.security.web.FilterChainProxy : Securing GET /oauth2/authorization/google-idp
2023-01-24T22:24:56.351+05:30 DEBUG 96235 --- [nio-9000-exec-3] o.s.s.web.DefaultRedirectStrategy : Redirecting to https://accounts.google.com/o/oauth2/v2/auth?response_type=code&client_id=12345&scope=openid%20https://www.googleapis.com/auth/userinfo.profile%20https://www.googleapis.com/auth/userinfo.email&state=LiD_tN32DWHRqSqplicP6DmLk9oYl4_jcW0koqBe4uc%3D&redirect_uri=http://localhost:9000/login/oauth2/code/google-idp&nonce=mEbeJ8BYMUG2snc7fQgr-BhvBd1Gw4SYIZsch6rp7Ck
2023-01-24T22:24:56.661+05:30 DEBUG 96235 --- [nio-9000-exec-4] o.s.security.web.FilterChainProxy : Securing GET /login/oauth2/code/google-idp?state=LiD_tN32DWHRqSqplicP6DmLk9oYl4_jcW0koqBe4uc%3D&code=4%2F0AWtgzh5Qn1pSQP9samBXt-s-A9NUT0LBaC0iwCps44rQnq1M7wVMG-bd5DQj_0HMaSLSRA&scope=email+profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+openid&authuser=0&prompt=none
2023-01-24T22:24:56.743+05:30 DEBUG 96235 --- [nio-9000-exec-4] o.s.web.client.RestTemplate : HTTP POST https://www.googleapis.com/oauth2/v4/token
2023-01-24T22:24:56.747+05:30 DEBUG 96235 --- [nio-9000-exec-4] o.s.web.client.RestTemplate : Accept=[application/json, application/*+json]
2023-01-24T22:24:56.748+05:30 DEBUG 96235 --- [nio-9000-exec-4] o.s.web.client.RestTemplate : Writing [{grant_type=[authorization_code], code=[4/0AWtgzh5Qn1pSQP9samBXt-s-A9NUT0LBaC0iwCps44rQnq1M7wVMG-bd5DQj_0HMaSLSRA], redirect_uri=[http://localhost:9000/login/oauth2/code/google-idp]}] as "application/x-www-form-urlencoded;charset=UTF-8"
2023-01-24T22:24:57.051+05:30 DEBUG 96235 --- [nio-9000-exec-4] o.s.web.client.RestTemplate : Response 200 OK
2023-01-24T22:24:57.052+05:30 DEBUG 96235 --- [nio-9000-exec-4] o.s.web.client.RestTemplate : Reading to [org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse] as "application/json;charset=utf-8"
2023-01-24T22:24:57.093+05:30 DEBUG 96235 --- [nio-9000-exec-4] o.s.web.client.RestTemplate : HTTP GET https://www.googleapis.com/oauth2/v3/certs
2023-01-24T22:24:57.094+05:30 DEBUG 96235 --- [nio-9000-exec-4] o.s.web.client.RestTemplate : Accept=[text/plain, application/json, application/*+json, */*]
2023-01-24T22:24:57.118+05:30 DEBUG 96235 --- [nio-9000-exec-4] o.s.web.client.RestTemplate : Response 200 OK
2023-01-24T22:24:57.118+05:30 DEBUG 96235 --- [nio-9000-exec-4] o.s.web.client.RestTemplate : Reading to [java.lang.String] as "application/json;charset=UTF-8"
2023-01-24T22:24:57.125+05:30 DEBUG 96235 --- [nio-9000-exec-4] .s.ChangeSessionIdAuthenticationStrategy : Changed session id from 856E5CB5EA53F6364793E21162F85AF2
2023-01-24T22:24:57.125+05:30 DEBUG 96235 --- [nio-9000-exec-4] o.s.s.w.csrf.CsrfAuthenticationStrategy : Replaced CSRF Token
2023-01-24T22:24:57.126+05:30 DEBUG 96235 --- [nio-9000-exec-4] w.c.HttpSessionSecurityContextRepository : Stored SecurityContextImpl [Authentication=OAuth2AuthenticationToken [Principal=Name: [***#gmail.com], Granted Authorities: [[OIDC_USER, SCOPE_https://www.googleapis.com/auth/userinfo.email, SCOPE_https://www.googleapis.com/auth/userinfo.profile, SCOPE_openid]], User Attributes: [{at_hash=ao1nlr-mAYrpo3nU3ODFUQ, sub=107668940011151070771, email_verified=true, iss=https://accounts.google.com, given_name=***, locale=en-GB, nonce=mEbeJ8BYMUG2snc7fQgr-BhvBd1Gw4SYIZsch6rp7Ck, picture=https://lh3.googleusercontent.com/a/AEdFTp75Udyj3805vIwRZpzku1-cRpiFpuMWsivqzRa9=s96-c, aud=[12345], azp=12345, name=*** *, exp=2023-01-24T17:54:57Z, family_name=*, iat=2023-01-24T16:54:57Z, email=***#gmail.com}], Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=0:0:0:0:0:0:0:1, SessionId=856E5CB5EA53F6364793E21162F85AF2], Granted Authorities=[OIDC_USER, SCOPE_https://www.googleapis.com/auth/userinfo.email, SCOPE_https://www.googleapis.com/auth/userinfo.profile, SCOPE_openid]]] to HttpSession [org.apache.catalina.session.StandardSessionFacade#46dcae35]
2023-01-24T22:24:57.126+05:30 DEBUG 96235 --- [nio-9000-exec-4] .s.o.c.w.OAuth2LoginAuthenticationFilter : Set SecurityContextHolder to OAuth2AuthenticationToken [Principal=Name: [***#gmail.com], Granted Authorities: [[OIDC_USER, SCOPE_https://www.googleapis.com/auth/userinfo.email, SCOPE_https://www.googleapis.com/auth/userinfo.profile, SCOPE_openid]], User Attributes: [{at_hash=ao1nlr-mAYrpo3nU3ODFUQ, sub=107668940011151070771, email_verified=true, iss=https://accounts.google.com, given_name=***, locale=en-GB, nonce=mEbeJ8BYMUG2snc7fQgr-BhvBd1Gw4SYIZsch6rp7Ck, picture=https://lh3.googleusercontent.com/a/AEdFTp75Udyj3805vIwRZpzku1-cRpiFpuMWsivqzRa9=s96-c, aud=[12345], azp=12345, name=*** *, exp=2023-01-24T17:54:57Z, family_name=*, iat=2023-01-24T16:54:57Z, email=***#gmail.com}], Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=0:0:0:0:0:0:0:1, SessionId=856E5CB5EA53F6364793E21162F85AF2], Granted Authorities=[OIDC_USER, SCOPE_https://www.googleapis.com/auth/userinfo.email, SCOPE_https://www.googleapis.com/auth/userinfo.profile, SCOPE_openid]]
Saving first-time user: name=***#gmail.com, claims={at_hash=ao1nlr-mAYrpo3nU3ODFUQ, sub=107668940011151070771, email_verified=true, iss=https://accounts.google.com, given_name=***, locale=en-GB, nonce=mEbeJ8BYMUG2snc7fQgr-BhvBd1Gw4SYIZsch6rp7Ck, picture=https://lh3.googleusercontent.com/a/AEdFTp75Udyj3805vIwRZpzku1-cRpiFpuMWsivqzRa9=s96-c, aud=[12345], azp=12345, name=*** *, exp=2023-01-24T17:54:57Z, family_name=*, iat=2023-01-24T16:54:57Z, email=***#gmail.com}, authorities=[OIDC_USER, SCOPE_https://www.googleapis.com/auth/userinfo.email, SCOPE_https://www.googleapis.com/auth/userinfo.profile, SCOPE_openid]
2023-01-24T22:24:57.126+05:30 DEBUG 96235 --- [nio-9000-exec-4] o.s.s.web.DefaultRedirectStrategy : Redirecting to http://localhost:9000/oauth2/authorize?response_type=code&client_id=messaging-client&scope=openid%20profile&state=2gTNT52oxL3kRqtnbA0vnXQzp3VrghJmLtVUNEtagRo%3D&redirect_uri=http://127.0.0.1:8080/login/oauth2/code/messaging-client-oidc&nonce=FTOwMi9WPU3zHBPBrG2Jj-Dxm0udS_dLfI1I0TiN2Ws&continue
2023-01-24T22:24:57.129+05:30 DEBUG 96235 --- [nio-9000-exec-5] o.s.security.web.FilterChainProxy : Securing GET /oauth2/authorize?response_type=code&client_id=messaging-client&scope=openid%20profile&state=2gTNT52oxL3kRqtnbA0vnXQzp3VrghJmLtVUNEtagRo%3D&redirect_uri=http://127.0.0.1:8080/login/oauth2/code/messaging-client-oidc&nonce=FTOwMi9WPU3zHBPBrG2Jj-Dxm0udS_dLfI1I0TiN2Ws&continue
2023-01-24T22:24:57.130+05:30 DEBUG 96235 --- [nio-9000-exec-5] w.c.HttpSessionSecurityContextRepository : Retrieved SecurityContextImpl [Authentication=OAuth2AuthenticationToken [Principal=Name: [***#gmail.com], Granted Authorities: [[OIDC_USER, SCOPE_https://www.googleapis.com/auth/userinfo.email, SCOPE_https://www.googleapis.com/auth/userinfo.profile, SCOPE_openid]], User Attributes: [{at_hash=ao1nlr-mAYrpo3nU3ODFUQ, sub=107668940011151070771, email_verified=true, iss=https://accounts.google.com, given_name=***, locale=en-GB, nonce=mEbeJ8BYMUG2snc7fQgr-BhvBd1Gw4SYIZsch6rp7Ck, picture=https://lh3.googleusercontent.com/a/AEdFTp75Udyj3805vIwRZpzku1-cRpiFpuMWsivqzRa9=s96-c, aud=[12345], azp=12345, name=*** *, exp=2023-01-24T17:54:57Z, family_name=*, iat=2023-01-24T16:54:57Z, email=***#gmail.com}], Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=0:0:0:0:0:0:0:1, SessionId=856E5CB5EA53F6364793E21162F85AF2], Granted Authorities=[OIDC_USER, SCOPE_https://www.googleapis.com/auth/userinfo.email, SCOPE_https://www.googleapis.com/auth/userinfo.profile, SCOPE_openid]]]
2023-01-24T22:24:59.025+05:30 DEBUG 96235 --- [nio-9000-exec-6] o.s.security.web.FilterChainProxy : Securing POST /oauth2/authorize
2023-01-24T22:24:59.026+05:30 DEBUG 96235 --- [nio-9000-exec-6] w.c.HttpSessionSecurityContextRepository : Retrieved SecurityContextImpl [Authentication=OAuth2AuthenticationToken [Principal=Name: [***#gmail.com], Granted Authorities: [[OIDC_USER, SCOPE_https://www.googleapis.com/auth/userinfo.email, SCOPE_https://www.googleapis.com/auth/userinfo.profile, SCOPE_openid]], User Attributes: [{at_hash=ao1nlr-mAYrpo3nU3ODFUQ, sub=107668940011151070771, email_verified=true, iss=https://accounts.google.com, given_name=***, locale=en-GB, nonce=mEbeJ8BYMUG2snc7fQgr-BhvBd1Gw4SYIZsch6rp7Ck, picture=https://lh3.googleusercontent.com/a/AEdFTp75Udyj3805vIwRZpzku1-cRpiFpuMWsivqzRa9=s96-c, aud=[12345], azp=12345, name=*** *, exp=2023-01-24T17:54:57Z, family_name=*, iat=2023-01-24T16:54:57Z, email=***#gmail.com}], Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=0:0:0:0:0:0:0:1, SessionId=856E5CB5EA53F6364793E21162F85AF2], Granted Authorities=[OIDC_USER, SCOPE_https://www.googleapis.com/auth/userinfo.email, SCOPE_https://www.googleapis.com/auth/userinfo.profile, SCOPE_openid]]]
2023-01-24T22:24:59.074+05:30 DEBUG 96235 --- [nio-9000-exec-6] o.s.s.web.DefaultRedirectStrategy : Redirecting to http://127.0.0.1:8080/login/oauth2/code/messaging-client-oidc?code=DxWgpwZqmepYInMZ0lBZrboaEVULZYep8r2I9Kz6MM9rY-2O2Bg1wSMiKPhwMM2U2Uf9bvd2N9pMFXbB7mCKw4GlDULdgNSADjHOzXQxdEGRNPtRVBU7i6OKfkxCtB7i&state=2gTNT52oxL3kRqtnbA0vnXQzp3VrghJmLtVUNEtagRo%3D

Grails 3.3.2 Spring Security Code & CAS

I am getting the following exception after entering my user name and pw into my CAS login form, Grails 3.3.2 app.
Configuring Spring Security Core ...
... finished configuring Spring Security Core
Configuring Spring Security CAS ...
... finished configuring Spring Security CAS
Grails application running at http://localhost:8089 in environment: development
2018-05-22 13:59:47.395 DEBUG --- [nio-8089-exec-2] o.j.c.c.session.SingleSignOutHandler : Recording session for token ST-1553-4NR7XWRPXGioiJXs9oLd-cas-01.mydomain.com
2018-05-22 13:59:47.395 DEBUG --- [nio-8089-exec-2] o.j.c.c.session.SingleSignOutHandler : Recording session for token ST-1553-4NR7XWRPXGioiJXs9oLd-cas-01.mydomain.com
2018-05-22 13:59:47.425 DEBUG --- [nio-8089-exec-2] c.c.s.HashMapBackedSessionMappingStorage : Attempting to remove Session=[7CBCC94E9BF728A044B05C07ABFAB894]
2018-05-22 13:59:47.425 DEBUG --- [nio-8089-exec-2] c.c.s.HashMapBackedSessionMappingStorage : Attempting to remove Session=[7CBCC94E9BF728A044B05C07ABFAB894]
2018-05-22 13:59:47.425 DEBUG --- [nio-8089-exec-2] c.c.s.HashMapBackedSessionMappingStorage : No mapping for session found. Ignoring.
2018-05-22 13:59:47.425 DEBUG --- [nio-8089-exec-2] c.c.s.HashMapBackedSessionMappingStorage : No mapping for session found. Ignoring.
2018-05-22 13:59:47.440 DEBUG --- [nio-8089-exec-2] o.j.c.c.v.Cas20ServiceTicketValidator : Placing URL parameters in map.
2018-05-22 13:59:47.440 DEBUG --- [nio-8089-exec-2] o.j.c.c.v.Cas20ServiceTicketValidator : Placing URL parameters in map.
2018-05-22 13:59:47.441 DEBUG --- [nio-8089-exec-2] o.j.c.c.v.Cas20ServiceTicketValidator : Calling template URL attribute map.
2018-05-22 13:59:47.441 DEBUG --- [nio-8089-exec-2] o.j.c.c.v.Cas20ServiceTicketValidator : Calling template URL attribute map.
2018-05-22 13:59:47.441 DEBUG --- [nio-8089-exec-2] o.j.c.c.v.Cas20ServiceTicketValidator : Loading custom parameters from configuration.
2018-05-22 13:59:47.441 DEBUG --- [nio-8089-exec-2] o.j.c.c.v.Cas20ServiceTicketValidator : Loading custom parameters from configuration.
2018-05-22 13:59:47.442 DEBUG --- [nio-8089-exec-2] o.j.c.c.v.Cas20ServiceTicketValidator : Constructing validation url: https://cas.mydomain.com/cas/serviceValidate?pgtUrl=http%3A%2F%2Flocalhost%3A8089%2Fsecure%2Freceptor&ticket=ST-1553-4NR7XWRPXGioiJXs9oLd-cas-01.mydomain.com&service=http%3A%2F%2Flocalhost%3A8089%2Flogin%2Fcas
2018-05-22 13:59:47.442 DEBUG --- [nio-8089-exec-2] o.j.c.c.v.Cas20ServiceTicketValidator : Constructing validation url: https://cas.mydomain.com/cas/serviceValidate?pgtUrl=http%3A%2F%2Flocalhost%3A8089%2Fsecure%2Freceptor&ticket=ST-1553-4NR7XWRPXGioiJXs9oLd-cas-01.mydomain.com&service=http%3A%2F%2Flocalhost%3A8089%2Flogin%2Fcas
2018-05-22 13:59:47.442 DEBUG --- [nio-8089-exec-2] o.j.c.c.v.Cas20ServiceTicketValidator : Retrieving response from server.
2018-05-22 13:59:47.442 DEBUG --- [nio-8089-exec-2] o.j.c.c.v.Cas20ServiceTicketValidator : Retrieving response from server.
2018-05-22 13:59:48.864 DEBUG --- [nio-8089-exec-2] o.j.c.c.v.Cas20ServiceTicketValidator : Server response:
2018-05-22 13:59:48.864 DEBUG --- [nio-8089-exec-2] o.j.c.c.v.Cas20ServiceTicketValidator : Server response:
2018-05-22 13:59:49.334 ERROR --- [nio-8089-exec-2] org.jasig.cas.client.util.XmlUtils : Premature end of file.
org.xml.sax.SAXParseException: Premature end of file.
at org.apache.xerces.util.ErrorHandlerWrapper.createSAXParseException(Unknown Source)
at org.apache.xerces.util.ErrorHandlerWrapper.fatalError(Unknown Source)
at org.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source)
at org.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source)
at org.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source)
at org.apache.xerces.impl.XMLVersionDetector.determineDocVersion(Unknown Source)
at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source)
at org.apache.xerces.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source)
at org.jasig.cas.client.util.XmlUtils.getTextForElement(XmlUtils.java:192)
serverUrlPrefix = 'http://cas.mydomain.com/cas'
Any ideas or suggestions would be appreciated!!!
Below is the output from my Grails 2.5.1 version of the same app and CAS server.
2018-05-18 10:42:26,755 DEBUG AbstractUrlBasedTicketValidator - Placing URL parameters in map.
2018-05-18 10:42:26,755 DEBUG AbstractUrlBasedTicketValidator - Calling template URL attribute map.
2018-05-18 10:42:26,756 DEBUG AbstractUrlBasedTicketValidator - Loading custom parameters from configuration.
2018-05-18 10:42:26,756 DEBUG AbstractUrlBasedTicketValidator - Constructing validation url: https://cas.mydomin.com/serviceValidate?ticket=ST-1485-7X6VirHikiEKadmDnt0Y-cas-01.mydomin.com&service=http%3A%2F%2Flocalhost%3A8089%2Fj_spring_cas_security_check
2018-05-18 10:42:26,756 DEBUG AbstractUrlBasedTicketValidator - Retrieving response from server.
2018-05-18 10:42:27,204 DEBUG AbstractUrlBasedTicketValidator - Server response:
<cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'>
<cas:authenticationSuccess>
<cas:user>first.lastname</cas:user>
</cas:authenticationSuccess>
</cas:serviceResponse>

Log4J2 in Wildfly 11- causing ERROR Unable to locate plugin

Wrote a simple web app that uses programmatic configuration of Log4J2 . ( no log4j2.xml )
The configurator snippet looks like below
ConfigurationBuilder<BuiltConfiguration> builder = ConfigurationBuilderFactory.newConfigurationBuilder();
builder.setStatusLevel(Level.ERROR);
builder.setConfigurationName("LogicLoggerConfigurations");
builder.setPackages("main.logging.config");
AppenderComponentBuilder appenderBuilderConsole = builder.newAppender("Stdout", "CONSOLE").addAttribute("target",
ConsoleAppender.Target.SYSTEM_OUT);
AppenderComponentBuilder appenderBuilderFile = builder.newAppender("toFile", "FILE").addAttribute("fileName",
"/pathto/logtest.log");
appenderBuilderConsole.add(builder.newLayout("PatternLayout")
.addAttribute("pattern", "%d [%t] %-5level: %msg%n%throwable"));
appenderBuilderFile.add(builder.newLayout("PatternLayout")
.addAttribute("pattern", "%d [%t] %-5level: %msg%n%throwable"));
AppenderComponentBuilder appenderBuilder = builder.newAppender("lacmem", "LogicMemoryAppender");
appenderBuilder.add(builder.newLayout("PatternLayout")
.addAttribute("pattern", "%d [%t] %-5level: %msg%n%throwable"));
builder.add(appenderBuilder);
builder.add(appenderBuilderConsole);
builder.add(appenderBuilderFile);
builder.add(builder.newLogger("main", Level.TRACE)
.add(builder.newAppenderRef("lacmem")).addAttribute("additivity", true));
builder.add(builder.newRootLogger(Level.ERROR).add(builder.newAppenderRef("Stdout"))
.add(builder.newAppenderRef("toFile")));
logicLoggerContext = Configurator.initialize(builder.build());
logicLoggerContext.updateLoggers();
There is a custom appender (plugin) under packages main.logging.config that looks like below
#Plugin(name = "LogicMemoryAppender", category = "Core", elementType = "appender", printObject = true)
public class LogicMemoryAppender extends AbstractAppender {
List<Map<String, Object>> logs = new CopyOnWriteArrayList<>();
protected LogicMemoryAppender(String name, Filter filter, Layout<? extends Serializable> layout, boolean ignoreExceptions) {
super(name, filter, layout, ignoreExceptions);
}
/*
*
* #see
* org.apache.logging.log4j.core.Appender#append(org.apache.logging.log4j.
* core.LogEvent)
*/
public void append(LogEvent event) {
Map<String, Object> logEntry = new HashMap<String, Object>();
logEntry.put("logger", event.getLoggerName());
if (null != event.getLevel())
logEntry.put("level", event.getLevel());
long millis = event.getTimeMillis();
logEntry.put("ts", millis);
logEntry.put("timestamp", "timestamp");
String exceptionText = "";
if (null != event.getThrown()) {
exceptionText = event.getThrown().getMessage();
}
String msg = event.getMessage().toString();
if (!msg.isEmpty()) {
msg = msg.replace("\"", "\\\"");
msg = msg.replace("\n", "\\n");
if (!exceptionText.isEmpty()) {
logEntry.put("message", msg + " : " + exceptionText);
} else {
logEntry.put("message", msg);
}
} else {
logEntry.put("message", exceptionText);
}
System.out.println("Log entry added "+logEntry);
logs.add(logEntry);
}
/**
* Factory method called by Log4j2 to initialize this appender.
* #param name
* #param layout
* #param filter
* #return
*/
#PluginFactory
public static LogicMemoryAppender createAppender(
#PluginAttribute("name") String name,
#PluginElement("Layout") Layout<? extends Serializable> layout,
#PluginElement("Filter") final Filter filter) {
if (name == null) {
LOGGER.error("No name provided for LogicMemoryAppender");
return null;
}
if (layout == null) {
layout = PatternLayout.createDefaultLayout();
}
return new LogicMemoryAppender(name, filter, layout, true);
}
}
The application is a servlet based app that has a single logging statement under doGet()
soloLogger = LogManager.getLogger();
soloLogger.trace("What is up");
I also disable the logging subsystem by adding the below config to Web-Inf
<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.2">
<deployment>
<exclude-subsystems>
<subsystem name="logging"/>
</exclude-subsystems>
</deployment>
</jboss-deployment-structure>
The application is deployed as a WAR file and uploaded to WildFly via the admin console.
Once i visit the URL, I see the below error in Wildfly console. The code works as expected for Tomcat8x and Weblogic 12.2.1.3 but not Jboss. :(
5:12:45,204 INFO [stdout] (default task-1) 2017-10-30 15:12:45,203 default task-1 ERROR Unable to locate plugin type for LogicMemoryAppender
15:12:45,237 INFO [stdout] (default task-1) 2017-10-30 15:12:45,237 default task-1 ERROR Unable to locate plugin for LogicMemoryAppender
15:12:45,247 INFO [stdout] (default task-1) 2017-10-30 15:12:45,246 default task-1 ERROR Unable to invoke factory method in class org.apache.logging.log4j.core.config.AppendersPlugin for element Appenders: java.lang.NullPointerException java.lang.NullPointerException
15:12:45,247 INFO [stdout] (default task-1) at org.apache.logging.log4j.core.config.plugins.visitors.PluginElementVisitor.visit(PluginElementVisitor.java:52)
15:12:45,247 INFO [stdout] (default task-1) at org.apache.logging.log4j.core.config.plugins.util.PluginBuilder.generateParameters(PluginBuilder.java:248)
15:12:45,247 INFO [stdout] (default task-1) at org.apache.logging.log4j.core.config.plugins.util.PluginBuilder.build(PluginBuilder.java:135)
15:12:45,247 INFO [stdout] (default task-1) at org.apache.logging.log4j.core.config.AbstractConfiguration.createPluginObject(AbstractConfiguration.java:958)
15:12:45,247 INFO [stdout] (default task-1) at org.apache.logging.log4j.core.config.AbstractConfiguration.createConfiguration(AbstractConfiguration.java:898)
15:12:45,247 INFO [stdout] (default task-1) at org.apache.logging.log4j.core.config.AbstractConfiguration.doConfigure(AbstractConfiguration.java:513)
15:12:45,247 INFO [stdout] (default task-1) at org.apache.logging.log4j.core.config.AbstractConfiguration.initialize(AbstractConfiguration.java:237)
15:12:45,247 INFO [stdout] (default task-1) at org.apache.logging.log4j.core.config.builder.impl.DefaultConfigurationBuilder.build(DefaultConfigurationBuilder.java:204)
15:12:45,247 INFO [stdout] (default task-1) at org.apache.logging.log4j.core.config.builder.impl.DefaultConfigurationBuilder.build(DefaultConfigurationBuilder.java:161)
15:12:45,247 INFO [stdout] (default task-1) at org.apache.logging.log4j.core.config.builder.impl.DefaultConfigurationBuilder.build(DefaultConfigurationBuilder.java:57)
15:12:45,247 INFO [stdout] (default task-1) at main.test.HanSolo.initConfig(HanSolo.java:63)
15:12:45,248 INFO [stdout] (default task-1) at main.test.HanSolo.<clinit>(HanSolo.java:23)
15:12:45,248 INFO [stdout] (default task-1) at main.test.TestLogging.doGet(TestLogging.java:31)
15:12:45,248 INFO [stdout] (default task-1) at javax.servlet.http.HttpServlet.service(HttpServlet.java:687)
15:12:45,248 INFO [stdout] (default task-1) at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
15:12:45,248 INFO [stdout] (default task-1) at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:85)
15:12:45,248 INFO [stdout] (default task-1) at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62)
15:12:45,248 INFO [stdout] (default task-1) at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)
15:12:45,248 INFO [stdout] (default task-1) at org.wildfly.extension.undertow.security.SecurityContextAssociationHandler.handleRequest(SecurityContextAssociationHandler.java:78)
15:12:45,248 INFO [stdout] (default task-1) at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
15:12:45,248 INFO [stdout] (default task-1) at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:131)
15:12:45,248 INFO [stdout] (default task-1) at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57)
15:12:45,248 INFO [stdout] (default task-1) at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
15:12:45,248 INFO [stdout] (default task-1) at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46)
15:12:45,248 INFO [stdout] (default task-1) at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64)
15:12:45,248 INFO [stdout] (default task-1) at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60)
15:12:45,248 INFO [stdout] (default task-1) at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77)
15:12:45,248 INFO [stdout] (default task-1) at io.undertow.security.handlers.NotificationReceiverHandler.handleRequest(NotificationReceiverHandler.java:50)
15:12:45,249 INFO [stdout] (default task-1) at io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43)
15:12:45,249 INFO [stdout] (default task-1) at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
15:12:45,249 INFO [stdout] (default task-1) at org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61)
15:12:45,249 INFO [stdout] (default task-1) at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
15:12:45,249 INFO [stdout] (default task-1) at org.wildfly.extension.undertow.deployment.GlobalRequestControllerHandler.handleRequest(GlobalRequestControllerHandler.java:68)
15:12:45,249 INFO [stdout] (default task-1) at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
15:12:45,249 INFO [stdout] (default task-1) at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:292)
15:12:45,249 INFO [stdout] (default task-1) at io.undertow.servlet.handlers.ServletInitialHandler.access$100(ServletInitialHandler.java:81)
15:12:45,249 INFO [stdout] (default task-1) at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:138)
15:12:45,249 INFO [stdout] (default task-1) at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:135)
15:12:45,249 INFO [stdout] (default task-1) at io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48)
15:12:45,249 INFO [stdout] (default task-1) at io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43)
15:12:45,249 INFO [stdout] (default task-1) at org.wildfly.extension.undertow.security.SecurityContextThreadSetupAction.lambda$create$0(SecurityContextThreadSetupAction.java:105)
15:12:45,249 INFO [stdout] (default task-1) at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1508)
15:12:45,249 INFO [stdout] (default task-1) at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1508)
15:12:45,249 INFO [stdout] (default task-1) at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1508)
15:12:45,249 INFO [stdout] (default task-1) at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1508)
15:12:45,249 INFO [stdout] (default task-1) at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:272)
15:12:45,249 INFO [stdout] (default task-1) at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:81)
15:12:45,249 INFO [stdout] (default task-1) at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:104)
15:12:45,249 INFO [stdout] (default task-1) at io.undertow.server.Connectors.executeRootHandler(Connectors.java:326)
15:12:45,250 INFO [stdout] (default task-1) at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:812)
15:12:45,250 INFO [stdout] (default task-1) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
15:12:45,250 INFO [stdout] (default task-1) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
15:12:45,250 INFO [stdout] (default task-1) at java.lang.Thread.run(Thread.java:745)
15:12:45,250 INFO [stdout] (default task-1)
15:12:45,250 INFO [stdout] (default task-1) 2017-10-30 15:12:45,250 default task-1 ERROR Unable to locate appender "Stdout" for logger config "root"
15:12:45,250 INFO [stdout] (default task-1) 2017-10-30 15:12:45,250 default task-1 ERROR Unable to locate appender "toFile" for logger config "root"
15:12:45,251 INFO [stdout] (default task-1) 2017-10-30 15:12:45,251 default task-1 ERROR Unable to locate appender "lacmem" for logger config "main"
Log4j2 does not seem to recognize the annotated plugin in WildFly. Not sure if this is a problem with log4j2 or WildFly.
JVM is Java 8x112
EDIT: Same error on WildFly 10 Final.
I could not find the solution for the problem referred above but i did find a workaround.
Instead of doing configuration programmatically, i combined it with an XML configuration file (log4j2.xml). Inside the XML, I initialized all the loggers that i use in the code.
Check out the official doc for more information on how to combine.
Then for the programmatic configuration
1. Create your own ConfigurationFactory that
2. returns an instance of your own XMLConfiguration ->Create a class that extends XMLConfiguration that manipulates and adds appenders to the above loggers ( LoggerConfig).
Once i am done changing the configuration, i called myloggercontext.updateLoggers() to load the changes. One thing to note here is that, to get your ConfigurationFactory registered, you will have to add a property file called log4j2.component.properties to the classpath. The content of my property file is as below
log4j.configurationFactory=main.logging.config.LogConfigurationFactory
This would make sure that your ConfigurationFactory gets loaded before any calls to the logger inside your app.
The above changes worked for JBoss as it was able to load the plugins as expected.

Unable to access the request.forwardURI after a 404 redirect

In my grails application I had a custom redirect for "404". Whenever the application used to hit a 404, it used to log the request.forwardURI and redirect the user to a 404 page. But after upgrading to wildfly-8.0.0(also tried 8.1.0 and 9.0.0-alpha), the application doesn't log the actual URI( request.forwardURI).
However, in the request dump I see the actual URI that was requested. I believe, it might not be a grails problem as the actual request is getting logged in jboss-4 and the jboss-eap-6.2.
The Request class in wildfly is HttpServletRequestImpl, whereas in older version it was ApplicationHttpRequest.
I have copied the war into https://www.dropbox.com/sh/trzzmfp7pp5ut0f/AADBDczE4fx1oJGDUAw8FxAqa?dl=0. Please let me know if is there any other way by which I can get the actual request.
Logs for wildfly
10:32:18,242 INFO [stdout] (default task-8) Request Class *** class io.undertow.servlet.spec.HttpServletRequestImpl
10:32:18,242 INFO [stdout] (default task-8) Request dump-------------------
10:32:18,245 INFO [stdout] (default task-8) <io.undertow.servlet.spec.HttpServletRequestImpl#6d806f8e exchange=HttpServerExchange{ GET /test1/grails/common/redirectUrl.dispatch} originalServletContext=io.undertow.servlet.spec.ServletContextImpl#4a622bb servletContext=io.undertow.servlet.spec.ServletContextImpl#4a622bb attributes=[javax.servlet.forward.request_uri:/test1/grails-errorhandler, org.springframework.web.servlet.DispatcherServlet.THEME_SOURCE:org.codehaus.groovy.grails.commons.spring.GrailsWebApplicationContext#52728c5: startup date [Thu Sep 18 10:31:55 IST 2014]; parent: Root WebApplicationContext, org.springframework.web.servlet.DispatcherServlet.THEME_RESOLVER:org.springframework.web.servlet.theme.FixedThemeResolver#39ec09de, javax.servlet.forward.context_path:/test1, javax.servlet.error.servlet_name:default, javax.servlet.error.message:Not Found, javax.servlet.forward.servlet_path:/grails-errorhandler, org.codehaus.groovy.grails.GRAILS_APPLICATION_ATTRIBUTES:org.codehaus.groovy.grails.web.servlet.DefaultGrailsApplicationAttributes#377beb87, urlMapping.FILTERED:true, charEncodingFilter.FILTERED:true, org.codehaus.groovy.grails.FLASH_SCOPE:[:], org.codehaus.groovy.grails.CONTROLLER_NAME_ATTRIBUTE:common, org.codehaus.groovy.grails.CONTROLLER:CommonController#28a40886, javax.servlet.error.request_uri:/test1/asdf, hiddenHttpMethod.FILTERED:true, grailsWebRequest.FILTERED:true, javax.servlet.forward.query_string:null, org.springframework.web.servlet.DispatcherServlet.FLASH_MAP_MANAGER:org.springframework.web.servlet.support.SessionFlashMapManager#292baa42, javax.servlet.forward.path_info:null, org.springframework.web.servlet.DispatcherServlet.CONTEXT:org.codehaus.groovy.grails.commons.spring.GrailsWebApplicationContext#52728c5: startup date [Thu Sep 18 10:31:55 IST 2014]; parent: Root WebApplicationContext, javax.servlet.error.status_code:404, org.codehaus.grails.INCLUDED_JS_LIBRARIES:[], org.codehaus.groovy.grails.ACTION_NAME_ATTRIBUTE:redirectUrl, org.codehaus.groovy.grails.web.sitemesh.GrailsPageFilter.GSP_SITEMESH_PAGE:org.codehaus.groovy.grails.web.sitemesh.GSPSitemeshPage#71b6e82b, org.springframework.web.servlet.DispatcherServlet.OUTPUT_FLASH_MAP:[:], com.opensymphony.sitemesh.APPLIED_ONCE:true, org.hibernate.impl.SessionFactoryImpl#22de1eda.PARTICIPATE:1, org.codehaus.groovy.grails.WEB_REQUEST:ServletWebRequest: uri=/test1/grails/common/redirectUrl.dispatch;client=127.0.0.1, org.springframework.web.servlet.DispatcherServlet.LOCALE_RESOLVER:org.springframework.web.servlet.i18n.SessionLocaleResolver#1f449960] servletInputStream=null reader=null cookies=null parts=null asyncStarted=false asyncContext=null queryParameters=[:[]] parsedFormData=null characterEncoding=UTF-8 readStarted=false sessionCookieSource=null>
10:32:18,246 INFO [stdout] (default task-8) ---------------------------
10:32:18,247 INFO [stdout] (default task-8) Request URI *** /test1/grails/common/redirectUrl.dispatch
10:32:18,249 INFO [stdout] (default task-8) Forward URI *** /test1/grails-errorhandler
Logs for older jboss
10:25:37,510 INFO [stdout] (http-/127.0.0.1:8080-1) Request Class *** class org.apache.catalina.core.ApplicationHttpRequest
10:25:37,510 INFO [stdout] (http-/127.0.0.1:8080-1) Request dump-------------------
10:25:37,514 INFO [stdout] (http-/127.0.0.1:8080-1) <org.apache.catalina.core.ApplicationHttpRequest#4cc7420c context=StandardEngine[jboss.web].StandardHost[default-host].StandardContext[/test1] contextPath=/test1 crossContext=false dispatcherType=1 parameters=[:] parsedParams=true pathInfo=null queryParamString=null queryString=null requestDispatcherPath=/grails-errorhandler requestURI=/test1/grails/common/redirectUrl.dispatch servletPath=/grails/common/redirectUrl.dispatch session=null specialAttributes=[null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] request=org.apache.catalina.core.ApplicationHttpRequest#1ad23c25>
10:25:37,514 INFO [stdout] (http-/127.0.0.1:8080-1) ------------URI and domainname --------------
10:25:37,515 INFO [stdout] (http-/127.0.0.1:8080-1) Request URI *** / /test1/grails/common/redirectUrl.dispatch
10:25:37,516 INFO [stdout] (http-/127.0.0.1:8080-1) Forward URI *** /test1/test
I was able to get the forwardURI through another workaround. Though, not the ideal way to get the forwardURI, but it worked for me.
forwardURI = request?.attributes.get("javax.servlet.error.request_uri")

Url Mapping fails for /oauth/token - Spring security + OAuth in a Grails application

I am building a grails application that includes:
Spring Security (Spring MVC project; NOT the Grails plugin)
"OAuth for Spring Security" to implement an OAuth2 provider
To accomplish this, I followed the following steps:
grails install-templates [see here]
in src/templates/war/web.xml, add the Spring Security filter as below:
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
define Spring Security and OAuth beans in WEB-INF/applicationContext.xml file including the following for handling /oauth/token
<http pattern="/oauth/token" create-session="stateless" authentication-manager-ref="clientAuthenticationManager"
xmlns="http://www.springframework.org/schema/security">
<intercept-url pattern="/oauth/token" access="IS_AUTHENTICATED_FULLY" />
<anonymous enabled="false" />
<http-basic entry-point-ref="clientAuthenticationEntryPoint" />
<!-- include this only if you need to authenticate clients via request parameters -->
<custom-filter ref="clientCredentialsTokenEndpointFilter" after="BASIC_AUTH_FILTER" />
<access-denied-handler ref="oauthAccessDeniedHandler" />
</http>
....
....
<oauth:authorization-server client-details-service-ref="clientDetails" token-services-ref="tokenServices">
<oauth:authorization-code />
<oauth:implicit />
<oauth:refresh-token />
<oauth:client-credentials />
<oauth:password />
</oauth:authorization-server>
Issue: The issue that I am facing is that Spring Security filters fire correctly and successfully authenticate the client. But after that, the GrailsDispatcherServlet is unable to find a handler for the POST to /oauth/token and returns a "404 Resource not found" error.
In the debug log, I can see that /oauth/token is mapped to a handler
2013-06-17 19:21:04,469 [localhost-startStop-1] INFO endpoint.FrameworkEndpointHandlerMapping - Mapped "{[/oauth/token],methods=[],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public org.springframework.http.ResponseEntity org.springframework.security.oauth2.provider.endpoint.TokenEndpoint.getAccessToken(java.security.Principal,java.lang.String,java.util.Map)
I suspect, this happens because when GrailsDispatcherServlet and ApplicationContext is created, the Grails' DefaultUrlMappingsHolder creates a new set of URL mappings in that context and replaces the previous set of mappings. For e.g., I also see the following in my debug log
2013-06-17 19:31:01,339 [localhost-startStop-1] DEBUG mapping.DefaultUrlMappingsHolder - Reverse mapping: [DefaultUrlMappingsHolder.UrlMappingKey#250f9a46 controller = 'account', action = [null], plugin = [null], params = set['API_VERSION']] -> /()/provisioning/order/account/()?
Here's the debug log for when I make an HTTP post to //oauth/token
2013-06-17 19:31:05,798 [http-bio-8080-exec-1] DEBUG util.AntPathRequestMatcher - Checking match of request : '/oauth/token'; against '/oauth/token'
2013-06-17 19:31:05,804 [http-bio-8080-exec-1] DEBUG web.FilterChainProxy - /oauth/token at position 1 of 5 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2013-06-17 19:31:05,805 [http-bio-8080-exec-1] DEBUG web.FilterChainProxy - /oauth/token at position 2 of 5 in additional filter chain; firing Filter: 'BasicAuthenticationFilter'
2013-06-17 19:31:05,807 [http-bio-8080-exec-1] DEBUG www.BasicAuthenticationFilter - Basic Authentication Authorization header found for user 'j2'
2013-06-17 19:31:05,808 [http-bio-8080-exec-1] DEBUG authentication.ProviderManager - Authentication attempt using org.springframework.security.authentication.dao.DaoAuthenticationProvider
2013-06-17 19:31:05,813 [http-bio-8080-exec-1] DEBUG www.BasicAuthenticationFilter - Authentication success: org.springframework.security.authentication.UsernamePasswordAuthenticationToken#ffff9a33: Principal: org.springframework.security.core.userdetails.User#d08: Username: j2; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ALL; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails#957e: RemoteIpAddress: 127.0.0.1; SessionId: null; Granted Authorities: ALL
2013-06-17 19:31:05,813 [http-bio-8080-exec-1] DEBUG web.FilterChainProxy - /oauth/token at position 3 of 5 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
2013-06-17 19:31:05,814 [http-bio-8080-exec-1] DEBUG web.FilterChainProxy - /oauth/token at position 4 of 5 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
2013-06-17 19:31:05,814 [http-bio-8080-exec-1] DEBUG web.FilterChainProxy - /oauth/token at position 5 of 5 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
2013-06-17 19:31:05,814 [http-bio-8080-exec-1] DEBUG util.AntPathRequestMatcher - Checking match of request : '/oauth/token'; against '/oauth/token'
2013-06-17 19:31:05,815 [http-bio-8080-exec-1] DEBUG intercept.FilterSecurityInterceptor - Secure object: FilterInvocation: URL: /oauth/token; Attributes: [IS_AUTHENTICATED_FULLY]
2013-06-17 19:31:05,815 [http-bio-8080-exec-1] DEBUG intercept.FilterSecurityInterceptor - Previously Authenticated: org.springframework.security.authentication.UsernamePasswordAuthenticationToken#ffff9a33: Principal: org.springframework.security.core.userdetails.User#d08: Username: j2; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ALL; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails#957e: RemoteIpAddress: 127.0.0.1; SessionId: null; Granted Authorities: ALL
2013-06-17 19:31:05,815 [http-bio-8080-exec-1] DEBUG vote.AffirmativeBased - Voter: org.springframework.security.access.vote.RoleVoter#35f3198f, returned: 0
2013-06-17 19:31:05,815 [http-bio-8080-exec-1] DEBUG vote.AffirmativeBased - Voter: org.springframework.security.access.vote.AuthenticatedVoter#6b1316f4, returned: 1
2013-06-17 19:31:05,815 [http-bio-8080-exec-1] DEBUG intercept.FilterSecurityInterceptor - Authorization successful
2013-06-17 19:31:05,816 [http-bio-8080-exec-1] DEBUG intercept.FilterSecurityInterceptor - RunAsManager did not change Authentication object
2013-06-17 19:31:05,816 [http-bio-8080-exec-1] DEBUG web.FilterChainProxy - /oauth/token reached end of additional filter chain; proceeding with original chain
2013-06-17 19:31:05,826 [http-bio-8080-exec-1] DEBUG mvc.GrailsWebRequestFilter - Bound Grails request context to thread: SecurityContextHolderAwareRequestWrapper[ FirewalledRequest[ org.apache.catalina.connector.RequestFacade#519cea9e]]
2013-06-17 19:31:05,846 [http-bio-8080-exec-1] DEBUG filter.UrlMappingsFilter - Executing URL mapping filter...
2013-06-17 19:31:05,847 [http-bio-8080-exec-1] DEBUG filter.UrlMappingsFilter - URL Mappings
------------
/
/(*)/provisioning/order/account/(*)?
/(*)/provisioning/order/demographics/(*)?
/(*)/provisioning/inventory/phone_numbers/(*)?
/(*)/billing/regions/(*)?
/(*)/billing/countries/(*)?
/(*)/provisioning/credit_cards/(*)?
/(*)/provisioning/states/(*)?
/(*)/provisioning/countries/(*)?
/(*)/provisioning/phone_cities/(*)?
/(*)/general/languages/(*)?
/(*)/docs/constraints/(*)?
2013-06-17 19:31:05,847 [http-bio-8080-exec-1] DEBUG mapping.DefaultUrlMappingsHolder - Attempting to match URI [/oauth/token] with pattern [/]
2013-06-17 19:31:05,847 [http-bio-8080-exec-1] DEBUG mapping.DefaultUrlMappingsHolder - Attempting to match URI [/oauth/token] with pattern [/(*)/provisioning/order/account/(*)?]
2013-06-17 19:31:05,847 [http-bio-8080-exec-1] DEBUG mapping.DefaultUrlMappingsHolder - Attempting to match URI [/oauth/token] with pattern [/(*)/provisioning/order/demographics/(*)?]
2013-06-17 19:31:05,848 [http-bio-8080-exec-1] DEBUG mapping.DefaultUrlMappingsHolder - Attempting to match URI [/oauth/token] with pattern [/(*)/provisioning/inventory/phone_numbers/(*)?]
2013-06-17 19:31:05,848 [http-bio-8080-exec-1] DEBUG mapping.DefaultUrlMappingsHolder - Attempting to match URI [/oauth/token] with pattern [/(*)/billing/regions/(*)?]
2013-06-17 19:31:05,848 [http-bio-8080-exec-1] DEBUG mapping.DefaultUrlMappingsHolder - Attempting to match URI [/oauth/token] with pattern [/(*)/billing/countries/(*)?]
2013-06-17 19:31:05,848 [http-bio-8080-exec-1] DEBUG mapping.DefaultUrlMappingsHolder - Attempting to match URI [/oauth/token] with pattern [/(*)/provisioning/credit_cards/(*)?]
2013-06-17 19:31:05,848 [http-bio-8080-exec-1] DEBUG mapping.DefaultUrlMappingsHolder - Attempting to match URI [/oauth/token] with pattern [/(*)/provisioning/states/(*)?]
2013-06-17 19:31:05,848 [http-bio-8080-exec-1] DEBUG mapping.DefaultUrlMappingsHolder - Attempting to match URI [/oauth/token] with pattern [/(*)/provisioning/countries/(*)?]
2013-06-17 19:31:05,848 [http-bio-8080-exec-1] DEBUG mapping.DefaultUrlMappingsHolder - Attempting to match URI [/oauth/token] with pattern [/(*)/provisioning/phone_cities/(*)?]
2013-06-17 19:31:05,848 [http-bio-8080-exec-1] DEBUG mapping.DefaultUrlMappingsHolder - Attempting to match URI [/oauth/token] with pattern [/(*)/general/languages/(*)?]
2013-06-17 19:31:05,848 [http-bio-8080-exec-1] DEBUG mapping.DefaultUrlMappingsHolder - Attempting to match URI [/oauth/token] with pattern [/(*)/docs/constraints/(*)?]
2013-06-17 19:31:05,857 [http-bio-8080-exec-1] DEBUG filter.UrlMappingsFilter - No match found, processing remaining filter chain.
2013-06-17 19:31:05,860 [http-bio-8080-exec-1] DEBUG mvc.GrailsWebRequestFilter - Cleared Grails thread-bound request context: SecurityContextHolderAwareRequestWrapper[ FirewalledRequest[ org.apache.catalina.connector.RequestFacade#519cea9e]]
2013-06-17 19:31:05,860 [http-bio-8080-exec-1] DEBUG access.ExceptionTranslationFilter - Chain processed normally
2013-06-17 19:31:05,860 [http-bio-8080-exec-1] DEBUG context.SecurityContextPersistenceFilter - SecurityContextHolder now cleared, as request processing completed
Any ideas on how to "share"/"propagate" those Spring /oauth/token mappings with the Grails Dispatcher?
I ran into similar symptoms when trying to get my /oauth/authorize endpoint to work properly. In order to get things going, I had to add the following to UrlMappings.groovy:
"/oauth/authorize" (uri:"/oauth/authorize.dispatch")
"/oauth/token" (uri:"/oauth/token.dispatch")
This solution came from examining the source for a grails spring-security-oauth provider plugin:
https://github.com/adaptivecomputing/grails-spring-security-oauth2-provider
Note that getting this setup to work completely might also involve updating the grails cache plugin: when using 1.0.1, I received a 500 after I got the mapping to work (when trying to load /oauth/authorize). Upgrading my cache plugin to 1.1.1 fixed that issue for me.
Hope something in there is useful.

Resources