soteria
soteria copied to clipboard
App-mem-custom-form securityContext looping
I am trying to implement the loginbacking according to the App-mem-custom-form and when I run:
@Inject
SecurityContext securityContext;
FacesContext context = FacesContext.getCurrentInstance();
Credential credential = new UsernamePasswordCredential(username, new Password(password));
AuthenticationStatus status = securityContext.authenticate(
getRequest(context),
getResponse(context),
withParams()
.credential(credential));
private static HttpServletResponse getResponse(FacesContext context) {
return (HttpServletResponse) context
.getExternalContext()
.getResponse();
}
private static HttpServletRequest getRequest(FacesContext context) {
return (HttpServletRequest) context
.getExternalContext()
.getRequest();
}
Instead of returning status(NOT_DONE, SEND_CONTINUE, SUCCESS, or SEND_FAILURE) it loops back and runs securityContext.authenticate infinitely. I have tried with both:
import javax.security.enterprise.SecurityContext;
import org.glassfish.soteria.SecurityContextImpl;
and I get the same looping issue with both. Hopefully just a maven dependancy issue on my part but I thought i'd check if anyone else was having this issue.
- Issue Imported From: https://github.com/javaee/security-soteria/issues/202
- Original Issue Raised By:@VincentMystery
- Original Issue Assigned To: Unassigned
@VincentMystery Commented (P.S. I am running a wildfly 11.0.0 server, and here is the log output when it loops:
soteria.SecurityContextImpl.authenticate(SecurityContextImpl.java:106)
at configuration.LoginBacking.login(LoginBacking.java:75)
at sun.reflect.GeneratedMethodAccessor41.invoke(ReflectionUtil.java:181)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.sun.el.util.ReflectionUtil.invokeMethod(ReflectionUtil.java:181)
at com.sun.el.parser.AstValue.invoke(AstValue.java:289)
at com.sun.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:304)
at org.jboss.weld.util.el.ForwardingMethodExpression.invoke(ForwardingMethodExpression.java:40)
at org.jboss.weld.el.WeldMethodExpression.invoke(WeldMethodExpression.java:50)
at org.jboss.weld.util.el.ForwardingMethodExpression.invoke(ForwardingMethodExpression.java:40)
at org.jboss.weld.el.WeldMethodExpression.invoke(WeldMethodExpression.java:50)
at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105)
at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:87)
at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102)
at javax.faces.component.UICommand.broadcast(UICommand.java:315)
at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:790)
at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1282)
at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:198)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:658)
at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:85)
at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62)
at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:274)
at io.undertow.servlet.handlers.ServletInitialHandler.dispatchToPath(ServletInitialHandler.java:209)
at io.undertow.servlet.spec.RequestDispatcherImpl.forwardImpl(RequestDispatcherImpl.java:221)
at io.undertow.servlet.spec.RequestDispatcherImpl.forwardImplSetup(RequestDispatcherImpl.java:147)
at io.undertow.servlet.spec.RequestDispatcherImpl.forward(RequestDispatcherImpl.java:111)
at io.undertow.servlet.handlers.security.ServletFormAuthenticationMechanism.servePage(ServletFormAuthenticationMechanism.java:145)
at io.undertow.security.impl.FormAuthenticationMechanism.sendChallenge(FormAuthenticationMechanism.java:176)
at io.undertow.security.impl.SecurityContextImpl$ChallengeSender.transition(SecurityContextImpl.java:296)
at io.undertow.security.impl.SecurityContextImpl$ChallengeSender.transition(SecurityContextImpl.java:314)
at io.undertow.security.impl.SecurityContextImpl$ChallengeSender.access$300(SecurityContextImpl.java:279)
at io.undertow.security.impl.SecurityContextImpl.sendChallenges(SecurityContextImpl.java:130)
at io.undertow.security.impl.SecurityContextImpl.authTransition(SecurityContextImpl.java:102)
at io.undertow.security.impl.SecurityContextImpl.authTransition(SecurityContextImpl.java:107)
at io.undertow.security.impl.SecurityContextImpl.authenticate(SecurityContextImpl.java:92)
at io.undertow.servlet.spec.HttpServletRequestImpl.authenticate(HttpServletRequestImpl.java:416)
at org.glassfish.soteria.mechanisms.jaspic.Jaspic.authenticate(Jaspic.java:112)
at org.glassfish.soteria.SecurityContextImpl.authenticate(SecurityContextImpl.java:106)
at configuration.LoginBacking.login(LoginBacking.java:75)
at sun.reflect.GeneratedMethodAccessor41.invoke(ReflectionUtil.java:181)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.sun.el.util.ReflectionUtil.invokeMethod(ReflectionUtil.java:181)
@arjantijms Commented From the stack it's clear that an Undertow native authentication mechanism is being installed (or defaulted to):
at io.undertow.security.impl.FormAuthenticationMechanism.sendChallenge(FormAuthenticationMechanism.java:176)
This particular authentication mechanism happens to forward to the same view from which you call securityContext.authenticate which (I think) makes use of the same request/post data and thus invokes the login method again, hence the loop.
Did you install a Java EE Security authentication mechanism?
@VincentMystery Commented Thank you for your help, I don't believe I installed two authentication mechanisms. I was trying to implement form biased authentication:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>Solid Building Solutions Application</display-name>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>/index.xhtml</welcome-file>
</welcome-file-list>
<context-param>
<param-name>primefaces.FONT_AWESOME</param-name>
<param-value>true</param-value>
</context-param>
<security-constraint>
<web-resource-collection>
<web-resource-name>user</web-resource-name>
<url-pattern>/user/*</url-pattern>
<http-method>GET</http-method>
</web-resource-collection>
<auth-constraint>
<role-name>EMPLOYEE</role-name>
<role-name>ADMIN</role-name>
</auth-constraint>
</security-constraint>
<security-constraint>
<web-resource-collection>
<web-resource-name>admin</web-resource-name>
<url-pattern>/admin/*</url-pattern>
<http-method>PUT</http-method>
<http-method>DELETE</http-method>
<http-method>GET</http-method>
<http-method>POST</http-method>
</web-resource-collection>
<auth-constraint>
<role-name>EMPLOYEE</role-name>
<role-name>ADMIN</role-name>
</auth-constraint>
</security-constraint>
<security-role>
<role-name>EMPLOYEE</role-name>
</security-role>
<security-role>
<role-name>ADMIN</role-name>
</security-role>
<login-config>
<auth-method>FORM</auth-method>
<form-login-config>
<form-login-page>/login.xhtml</form-login-page>
<form-error-page>/error.xhtml</form-error-page>
</form-login-config>
</login-config>
<!--<servlet>-->
<!--<servlet-name>RFIDResource</servlet-name>-->
<!--<servlet-class>Servlets.RFIDResource</servlet-class>-->
<!--</servlet>-->
<!---->
<!--<servlet-mapping>-->
<!--<servlet-name>RFIDResource</servlet-name>-->
<!--<url-pattern>/RFIDResource</url-pattern>-->
<!--</servlet-mapping>-->
</web-app>
And then I am using javax.security.enterprise and Sorteria as per the example projects.
@arjantijms Commented
<login-config>
<auth-method>FORM</auth-method>
This will cause io.undertow.security.impl.FormAuthenticationMechanism to be installed, which causes the looping here.
The idea is to have an authentication mechanism installed that's Java EE Security aware. I.e. using:
@FormAuthenticationMechanismDefinition(
loginToContinue = @LoginToContinue(
loginPage="/login-servlet",
errorPage="/login-error-servlet"
)
See: https://github.com/javaee/security-soteria/blob/master/test/app-mem-form/src/main/java/org/glassfish/soteria/test/ApplicationConfig.java#L47
@VincentMystery Commented Thank you very much for your help. Your suggestion worked and fixed the looping issue. Now I just get a blank page that says "forbidden" when I try to go to a restricted page instead of the login form. This is most likely an issue with my setup and not the JSR.
@VincentMystery do you need any more help? Can we safely closed this issue?