如何在Wildfly 8上的Picketbox / Undertow中捕获FailedLoginException以应用CORS

在ContainerResponseFilter的帮助下,我能够将CORS头应用于所有传出的响应,并且使用ExceptionMapper,我可以在所有错误和exception上执行相同的操作, 除了 Picketbox / Undertow应该在Wildfly中抛出的任何与身份validation相关的exception。

无论我尝试什么,我的ExceptionMapper都不会捕获它,因此,前端无法读取401状态,因为响应没有附加CORS头(XHR HTTP状态代码只是变为0)。

我正在使用这个 PBKDF2设置来对MySQL数据库进行身份validation,起初我认为可能因为身份validation是在一个单独的模块中运行的,所以我的应用程序没有捕获它,但即使将所有身份validation代码移到我自​​己的身份之后也是如此应用程序我有同样的问题。

这是我尝试使用错误密码进行身份validation时获得的日志条目(当我根本不发送任何凭据时,我得到一个非常类似的日志条目):

2014-11-29 16:11:08,053 TRACE [org.jboss.security](默认任务-4)PBOX000224:结束getAppConfigurationEntry(PBKDF2DatabaseDomain),AuthInfo:AppConfigurationEntry []:[0] LoginModule类:com.example.myapplication。 security.SaltedDatabaseServerLoginModule ControlFlag:LoginModuleControlFlag:required选项:name = dsJndiName,value = java:/ user name = principalsQuery,value = SELECT Hash FROM account WHERE ID =? name = rolesQuery,value = SELECT Role ,’角色’FROM帐户WHERE accountID =?

2014-11-29 16:11:08,053 TRACE [org.jboss.security](默认任务-4)PBOX000236:开始初始化方法2014-11-29 16:11:08,053 TRACE [org.jboss.security](默认任务-4)PBOX000262:模块选项[dsJndiName:java:/ user,principalsQuery:SELECT Hash FROM account WHERE ID = ?, rolesQuery:SELECT Role ,’Roles’FROM account WHERE accountID =?,suspendResume:true] 2014-11-29 16:11:08,053 TRACE [org.jboss.security](默认任务-4)PBOX000240:开始登录方法2014-11-29 16:11:08,053 TRACE [org .jboss.security](默认任务-4)PBOX000263:执行查询SELECT Hash FROM account WHERE ID =? 用户名1@2.se 2014-11-29 16:11:08,062 DEBUG [org.jboss.security](默认任务-4)PBOX000283:用户名1@2.com密码错误2014-11-29 16:11 :08,062 TRACE [org.jboss.security](默认任务-4)PBOX000244:开始中止方法2014-11-29 16:11:08,062 DEBUG [org.jboss.security](默认任务-4)PBOX000206:登录失败: javax.security.auth.login.FailedLoginException:PBOX000070:密码无效/密码无效org.jboss.security.auth.spi.UsernamePasswordLoginModule.login(UsernamePasswordLoginModule.java:284)[picketbox-4.0.21.Beta1.jar:4.0 .21.Beta1] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)[rt.jar:1.8.0_25] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)[rt.jar:1.8.0_25]在sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)[rt.jar:1.8.0_25] java.lang.reflect.Method.invoke(Method.java:483)[rt.jar:1.8.0_25]在javax.security.auth.login.LoginContext.invoke(LoginContext.java:755)[r t.jar:1.8.0_25] at javax.security.auth.login.LoginContext.access $ 000(LoginContext.java:195)[rt.jar:1.8.0_25] at javax.security.auth.login.LoginContext $ 4.run (LoginContext.java:682)[rt.jar:1.8.0_25]在java.security的javax.security.auth.login.LoginContext $ 4.run(LoginContext.java:680)[rt.jar:1.8.0_25]。来自javax.security.auth的javax.security.auth.login.LoginContext.invokePriv(LoginContext.java:680)[rt.jar:1.8.0_25]的AccessController.doPrivileged(本地方法)[rt.jar:1.8.0_25] .login.LoginContext.login(LoginContext.java:587)[rt.jar:1.8.0_25] at org.jboss.security.authentication.JBossCachedAuthenticationManager.defaultLogin(JBossCachedAuthenticationManager.java:408)[picketbox-infinispan-4.0.21。 Beta.jar:4.0.21.Beta1]在org.jboss.security.authentication.JBossCachedAuthenticationManager.proceedWithJaasLogin(JBossCachedAuthenticationManager.java:345)[picketbox-infinispan-4.0.21.Beta1.jar:4.0.21.Beta1] at org .jboss.security.authentication.JBossCachedAuthenticationManager.authenticate( JBossCachedAuthenticationManager.java:333)[picketbox-infinispan-4.0.21.Beta1.jar:4.0.21.Beta1] at org.jboss.security.authentication.JBossCachedAuthenticationManager.isValid(JBossCachedAuthenticationManager.java:146)[picketbox-infinispan-4.0 .21.Beta1.jar:4.0.21.Beta1] atg.wildfly.extension.undertow.security.JAASIdentityManagerImpl.verifyCredential(JAASIdentityManagerImpl.java:111)at org.wildfly.extension.undertow.security.JAASIdentityManagerImpl.verify(JAASIdentityManagerImpl .java:82)在io.undertow.security的io.undertow.security.impl.BasicAuthenticationMechanism.authenticate(BasicAuthenticationMechanism.java:110) [undertow-core-1.0.15.Final.jar:1.0.15.Final]。 impo.SecurityContextImpl $ AuthAttempter.transition(SecurityContextImpl.java:281)[lowow-core- 1.0.15.Final.jar:1.0.15.Final] at io.undertow.security.impl.SecurityContextImpl $ AuthAttempter.transition(SecurityContextImpl。 java:298)[undertow-core-1.0.15.Final.jar:1.0.15.Final] at io.undertow.security.impl.SecurityContextImpl $ AutoAttempter.access $ 100(SecurityContextImpl.java:268)[afow-core-1.0.15.Final.jar:1.0.15.Final] at io.undertow.security.impl.SecurityContextImpl.attemptAuthentication(SecurityContextImpl.java:131)[ undero-core-1.0.15.Final.jar:1.0.15.Final] at io.undertow.security.impl.SecurityContextImpl.authTransition(SecurityContextImpl.java:106)[undertow-core-1.0.15.Final.jar:在io.undertow.servlet的io.undertow.security.impl.SecurityContextImpl.authenticate(SecurityContextImpl.java:99)[undertow-core-1.0.15.Final.jar:1.0.15.Final]的1.0.15.Final] .handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:54)[undertow-servlet-1.0.15.Final.jar:1.0.15.Final] at io.undertow.server.handlers.DisableCacheHandler.handleRequest(DisableCacheHandler.java :27)[underow-core-1.0.15.Final.jar:1.0.15.Final] at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:25)[undertow-core-1.0.15。 Final.jar:1.0.15.Final] at io.undertow.securit y.handlers.AuthenticationConstraintHandler.handleRequest(AuthenticationConstraintHandler.java:51)[undertow-core-1.0.15.Final.jar:1.0.15.Final] at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java: 45)[endow-core-1.0.15.Final.jar:1.0.15.Final] at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:61)[undertow-servlet-1.0.15 .Final.jar:1.0.15.Final] at io.undertow.servlet.handlers.security.ServletSecurityConstraintHandler.handleRequest(ServletSecurityConstraintHandler.java:56)[undertow-servlet-1.0.15.Final.jar:1.0.15.Final ]在io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:58)[undertow-core-1.0.15.Final.jar:1.0.15.Final] at io.undertow.servlet.handlers.security。 CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:70)[undertow-servlet-1.0。 15.Final.jar:1.0.15.Final] at io.undertow.security.handlers.SecurityInitialHandler.handleRequest(SecurityInitialHandler.java:76)[undertow-core-1.0.15.Final.jar:1.0.15.Final]在org.wildfly.extension.undertow.security.jacc的io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:25)[undertow-core-1.0.15.Final.jar:1.0.15.Final] JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61)at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:25)[undertow-core-1.0.15.Final.jar:1.0.15.Final] at at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:25)[undertow-core-1.0.15.Final.jar:1.0.15.Final] at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest( ServletInitialHandler.java:240)[lowow- servlet-1.0.15.Final.jar:1.0.15.Final] at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:227)[postow- servlet-1.0 .15.Final.jar:1.0.15.Final] at io .undertow.servlet.handlers.ServletInitialHandler.access $ 000(ServletInitialHandler.java:73)[undertow-servlet-1.0.15.Final.jar:1.0.15.Final] at io.undertow.servlet.handlers.ServletInitialHandler $ 1.handleRequest (ServletInitialHandler.java:146)[undertow-servlet-1.0.15.Final.jar:1.0.15.Final] at io.undertow.server.Connectors.executeRootHandler(Connectors.java:177)[undertow-core-1.0。 15.Final.jar:1.0.15.Final] at io.undertow.server.HttpServerExchange $ 1.run(HttpServerExchange.java:727)[undertow-core-1.0.15.Final.jar:1.0.15.Final] at at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)[rt.jar:1.8.0_25] at java.util.concurrent.ThreadPoolExecutor $ Worker.run(ThreadPoolExecutor.java:617)[rt.jar:1.8 .0_25]在java.lang.Thread.run(Thread.java:745)[rt.jar:1.8.0_25]

这是我的ExceptionMapper类(目前设置为捕获所有Throwables徒劳地尝试使其工作):

 @Provider public class NotAuthorizedExceptionMapper implements ExceptionMapper{ @Override public Response toResponse(Throwable exception) { Response response = Response.status(Response.Status.UNAUTHORIZED).build(); response.getHeaders().putSingle("Access-Control-Allow-Origin", "*"); response.getHeaders().putSingle("Access-Control-Allow-Methods", "OPTIONS, GET, POST, PUT, DELETE"); response.getHeaders().putSingle("Access-Control-Allow-Headers", "origin, content-type, accept, authorization, access-control-allow-origin, access-control-allow-methods, access-control-allow-headers, allow, content-length, date, last-modified"); return response; } 

我该怎么做才能捕获这些身份validationexception,从而将CORS附加到它们身上?

最后,我设法通过修改配置文件(standalone.xml)来确定您可以在Wildfly上的所有非错误传出响应中添加自定义标头。 这解决了我的问题:

                         

编辑:原来Wildfly没有将CORS标题附加到未经授权的响应中,但是当它遇到500个错误时,它会非常巧妙地忽略它们。 任何关于如何解决这个问题的想法都将受到高度赞赏。