Forgotten password - Bogus User Policy combined with external OAuth verification method does not work

At a customer, we integrated SSPR's forgotten password with an external provider via OAuth so that users can use this as a verification method when they have forgotten their password.

We had something similar configured on SSPR 4.6, but that used OSP, now with SSPR 4.7, we are calling an external OAuth provider instead.

This all works correctly until we enable the Bogus User Policy.

When that happens we get a 5015 error and the following stack trace in the SSPR.log

2024-06-24T16:55:33Z, DEBUG, search.UserSearchEngine, {781} searchID=1 completed user search process in 0ms, intermediate result size=0 [x.x.x.x]
2024-06-24T16:55:35Z, ERROR, servlet.AbstractPwmServlet, {781} unexpected error during action handler for 'password.pwm.http.servlet.forgottenpw.ForgottenPasswordServlet:search', error: unexpected method during forward: OAUTH [x.x.x.x] (stacktrace follows)
java.lang.UnsupportedOperationException: unexpected method during forward: OAUTH
	at password.pwm.http.servlet.forgottenpw.ForgottenPasswordUtil.initBogusForgottenPasswordBean2(ForgottenPasswordUtil.java:651)
	at password.pwm.http.servlet.forgottenpw.ForgottenPasswordUtil.initBogusForgottenPasswordBean(ForgottenPasswordUtil.java:569)
	at password.pwm.http.servlet.forgottenpw.ForgottenPasswordServlet.processSearch(ForgottenPasswordServlet.java:526)
	at jdk.internal.reflect.GeneratedMethodAccessor129.invoke(Unknown Source)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at password.pwm.http.servlet.ControlledPwmServlet.dispatchMethod(ControlledPwmServlet.java:119)
	at password.pwm.http.servlet.ControlledPwmServlet.processAction(ControlledPwmServlet.java:159)
	at password.pwm.http.servlet.AbstractPwmServlet.handleRequest(AbstractPwmServlet.java:123)
	at password.pwm.http.servlet.AbstractPwmServlet.doPost(AbstractPwmServlet.java:73)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:555)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:623)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:209)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153)
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153)
	at password.pwm.http.filter.AbstractPwmFilter$PwmFilterChain.doFilter(AbstractPwmFilter.java:153)
	at password.pwm.http.filter.SessionFilter.processFilter(SessionFilter.java:110)
	at password.pwm.http.filter.AbstractPwmFilter.doFilter(AbstractPwmFilter.java:97)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153)
	at password.pwm.http.filter.AbstractPwmFilter$PwmFilterChain.doFilter(AbstractPwmFilter.java:153)
	at password.pwm.http.filter.ApplicationModeFilter.processFilter(ApplicationModeFilter.java:80)
	at password.pwm.http.filter.AbstractPwmFilter.doFilter(AbstractPwmFilter.java:97)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153)
	at password.pwm.http.filter.AbstractPwmFilter$PwmFilterChain.doFilter(AbstractPwmFilter.java:153)
	at password.pwm.http.filter.ObsoleteUrlFilter.processFilter(ObsoleteUrlFilter.java:50)
	at password.pwm.http.filter.AbstractPwmFilter.doFilter(AbstractPwmFilter.java:97)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153)
	at password.pwm.http.filter.RequestInitializationFilter.initializeServletRequest(RequestInitializationFilter.java:244)
	at password.pwm.http.filter.RequestInitializationFilter.doFilter(RequestInitializationFilter.java:166)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153)
	at com.github.ziplet.filter.compression.CompressingFilter.doFilter(CompressingFilter.java:263)
	at password.pwm.http.filter.GZIPFilter.doFilter(GZIPFilter.java:79)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:168)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:596)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:130)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93)
	at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:670)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:390)
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63)
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:928)
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1794)
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52)
	at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
	at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	at java.base/java.lang.Thread.run(Thread.java:829)

java.lang.UnsupportedOperationException: unexpected method during forward: OAUTH
	at password.pwm.http.servlet.forgottenpw.ForgottenPasswordUtil.initBogusForgottenPasswordBean2(ForgottenPasswordUtil.java:651) ~[sspr-server-4.7.0.2.jar:4.7.0.2]
	at password.pwm.http.servlet.forgottenpw.ForgottenPasswordUtil.initBogusForgottenPasswordBean(ForgottenPasswordUtil.java:569) ~[sspr-server-4.7.0.2.jar:4.7.0.2]
	at password.pwm.http.servlet.forgottenpw.ForgottenPasswordServlet.processSearch(ForgottenPasswordServlet.java:526) ~[sspr-server-4.7.0.2.jar:4.7.0.2]
	at jdk.internal.reflect.GeneratedMethodAccessor129.invoke(Unknown Source) ~[?:?]
	at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
	at java.lang.reflect.Method.invoke(Method.java:566) ~[?:?]
	at password.pwm.http.servlet.ControlledPwmServlet.dispatchMethod(ControlledPwmServlet.java:119) [sspr-server-4.7.0.2.jar:4.7.0.2]
	at password.pwm.http.servlet.ControlledPwmServlet.processAction(ControlledPwmServlet.java:159) [sspr-server-4.7.0.2.jar:4.7.0.2]
	at password.pwm.http.servlet.AbstractPwmServlet.handleRequest(AbstractPwmServlet.java:123) [sspr-server-4.7.0.2.jar:4.7.0.2]
	at password.pwm.http.servlet.AbstractPwmServlet.doPost(AbstractPwmServlet.java:73) [sspr-server-4.7.0.2.jar:4.7.0.2]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:555) [servlet-api.jar:4.0.FR]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:623) [servlet-api.jar:4.0.FR]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:209) [catalina.jar:9.0.85]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153) [catalina.jar:9.0.85]
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) [tomcat-websocket.jar:9.0.85]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178) [catalina.jar:9.0.85]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153) [catalina.jar:9.0.85]
	at password.pwm.http.filter.AbstractPwmFilter$PwmFilterChain.doFilter(AbstractPwmFilter.java:153) [sspr-server-4.7.0.2.jar:4.7.0.2]
	at password.pwm.http.filter.SessionFilter.processFilter(SessionFilter.java:110) [sspr-server-4.7.0.2.jar:4.7.0.2]
	at password.pwm.http.filter.AbstractPwmFilter.doFilter(AbstractPwmFilter.java:97) [sspr-server-4.7.0.2.jar:4.7.0.2]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178) [catalina.jar:9.0.85]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153) [catalina.jar:9.0.85]
	at password.pwm.http.filter.AbstractPwmFilter$PwmFilterChain.doFilter(AbstractPwmFilter.java:153) [sspr-server-4.7.0.2.jar:4.7.0.2]
	at password.pwm.http.filter.ApplicationModeFilter.processFilter(ApplicationModeFilter.java:80) [sspr-server-4.7.0.2.jar:4.7.0.2]
	at password.pwm.http.filter.AbstractPwmFilter.doFilter(AbstractPwmFilter.java:97) [sspr-server-4.7.0.2.jar:4.7.0.2]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178) [catalina.jar:9.0.85]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153) [catalina.jar:9.0.85]
	at password.pwm.http.filter.AbstractPwmFilter$PwmFilterChain.doFilter(AbstractPwmFilter.java:153) [sspr-server-4.7.0.2.jar:4.7.0.2]
	at password.pwm.http.filter.ObsoleteUrlFilter.processFilter(ObsoleteUrlFilter.java:50) [sspr-server-4.7.0.2.jar:4.7.0.2]
	at password.pwm.http.filter.AbstractPwmFilter.doFilter(AbstractPwmFilter.java:97) [sspr-server-4.7.0.2.jar:4.7.0.2]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178) [catalina.jar:9.0.85]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153) [catalina.jar:9.0.85]
	at password.pwm.http.filter.RequestInitializationFilter.initializeServletRequest(RequestInitializationFilter.java:244) [sspr-server-4.7.0.2.jar:4.7.0.2]
	at password.pwm.http.filter.RequestInitializationFilter.doFilter(RequestInitializationFilter.java:166) [sspr-server-4.7.0.2.jar:4.7.0.2]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178) [catalina.jar:9.0.85]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153) [catalina.jar:9.0.85]
	at com.github.ziplet.filter.compression.CompressingFilter.doFilter(CompressingFilter.java:263) [ziplet-2.4.1.jar:?]
	at password.pwm.http.filter.GZIPFilter.doFilter(GZIPFilter.java:79) [sspr-server-4.7.0.2.jar:4.7.0.2]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178) [catalina.jar:9.0.85]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153) [catalina.jar:9.0.85]
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:168) [catalina.jar:9.0.85]
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90) [catalina.jar:9.0.85]
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:596) [catalina.jar:9.0.85]
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:130) [catalina.jar:9.0.85]
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93) [catalina.jar:9.0.85]
	at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:670) [catalina.jar:9.0.85]
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) [catalina.jar:9.0.85]
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342) [catalina.jar:9.0.85]
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:390) [tomcat-coyote.jar:9.0.85]
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63) [tomcat-coyote.jar:9.0.85]
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:928) [tomcat-coyote.jar:9.0.85]
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1794) [tomcat-coyote.jar:9.0.85]
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) [tomcat-coyote.jar:9.0.85]
	at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) [tomcat-util.jar:9.0.85]
	at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) [tomcat-util.jar:9.0.85]
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-util.jar:9.0.85]
	at java.lang.Thread.run(Thread.java:829) [?:?]
2024-06-24T16:55:35Z, FATAL, servlet.AbstractPwmServlet, {781} unexpected error: 5015 ERROR_INTERNAL (unexpected error during action handler for 'password.pwm.http.servlet.forgottenpw.ForgottenPasswordServlet:search', error: unexpected method during forward: OAUTH) [x.x.x.x]
2024-06-24T16:55:35Z, DEBUG, servlet.AbstractPwmServlet, null
2024-06-24T16:55:35Z, ERROR, http.PwmResponse, {781} 5015 ERROR_INTERNAL (unexpected error during action handler for 'password.pwm.http.servlet.forgottenpw.ForgottenPasswordServlet:search', error: unexpected method during forward: OAUTH) [x.x.x.x]
2024-06-24T16:55:35Z, DEBUG, http.PwmResponse, {781} forcing logout due to error 5015 ERROR_INTERNAL (unexpected error during action handler for 'password.pwm.http.servlet.forgottenpw.ForgottenPasswordServlet:search', error: unexpected method during forward: OAUTH) [x.x.x.x]

This defeats the entire purpose of the Bogus User Policy, in that this stack trace/error only occurs when a match is not found.

Turning Bogus User Policy feature off - stops the stack traces from appearing, but allows one to discover if a user exists or not in the directory that SSPR is configured to search against.

This functionality should "just work" in an equal manner for all verification methods. Why is OAUTH treated specially here?

  • Suggested Answer

    0  

    Hi Alex,

    Could you open a case with support so we could assist you with this.

    Regards

    Liam O'Dowd

  • 0   in reply to   

    I have now opened a case for this, which is assigned to you Liam, further testing shows that bogus user policy does work for a limited subset of verification methods, for example with SMS token, but not with for example others, including OAuth or LDAP attributes.

    Guessing that there needs to be a specific code path to handle each new verification method and that only some are actually implemented.
    Which makes this option rather useless in the real world.

    It also does not align with the documentation which states that it will "act as if the invalid user searches are valid, and display such users with a fake forgotten password policy. This policy prevents username discovery."

    When the verification method can't handle this bogus user feature. One can easily determine if a user exists or not, because if they do not exist, SSPR throws 5015 ERROR_INTERNAL