-
15. Re: Advance authentication
kapitanpetko Nov 30, 2009 10:17 AM (in response to itays100)
Itay Sahar wrote on Nov 30, 2009 10:11:
Override remember me as well ? if yes which encoding should we use instead.
In addition, we should add a bug to jira about this as well.You might have to override if it is indeed a bug. Attach a debugger to see what exactly happens first. Then you can decide how/if to fix it.
-
16. Re: Advance authentication
itays100 Nov 30, 2009 8:33 PM (in response to itays100)After debug i came with some results:
The following code works with no exception!
from RememberMe component:
protected String encodeToken(String username, String value) { StringBuilder sb = new StringBuilder(); sb.append(username); sb.append(":"); sb.append(value); return Base64.encodeBytes(sb.toString().getBytes()); }
The addCookie throw the exception:
protected void setCookieValueIfEnabled(String value) { FacesContext ctx = FacesContext.getCurrentInstance(); if ( isCookieEnabled() && ctx != null) { HttpServletResponse response = (HttpServletResponse) ctx.getExternalContext().getResponse(); Cookie cookie = new Cookie( getCookieName(), value ); cookie.setMaxAge( getCookieMaxAge() ); cookie.setPath(cookiePath); response.addCookie(cookie); } }
It seems to me that encodeToken from rememberMe should be override to support this advance feature. Any idea how we can
encode this to support special character. -
17. Re: Advance authentication
kapitanpetko Dec 1, 2009 2:54 AM (in response to itays100)What is the input/output of encodeToken()? What is your locale? Depending on this getBytes() might return different things, although that might not be relevant.
-
18. Re: Advance authentication
itays100 Dec 1, 2009 11:32 PM (in response to itays100)Input is:
username= aaa.bbb@ccc.com value= 6de5ca4f:1254c461110:-7feb:9135486247122677484
Output is:
aXRheS5zYWhhckBnbWFpbC5jb206NmRlNWNhNGY6MTI1NGM0NjExMTA6LTdmZWI6OTEzNTQ4NjI0 FacesContext.getCurrentInstance().getExternalContext().getRequestLocale() return en_US
Thanks!
-
19. Re: Advance authentication
kapitanpetko Dec 2, 2009 2:20 AM (in response to itays100)
Itay Sahar wrote on Dec 01, 2009 23:32:
Output is:aXRheS5zYWhhckBnbWFpbC5jb206NmRlNWNhNGY6MTI1NGM0NjExMTA6LTdmZWI6OTEzNTQ4NjI0
That is valid Base64 (it has your gmail in it :)), so might be a problem with your application server, rather than Seam. What server/version are you using? Try with a newer version if you have that option.
-
-
21. Re: Advance authentication
kapitanpetko Dec 2, 2009 11:59 AM (in response to itays100)
Itay Sahar wrote on Dec 02, 2009 09:28:
tomcat 6.0.18Try the newest version.
-
22. Re: Advance authentication
itays100 Dec 5, 2009 1:50 AM (in response to itays100)this didn't help. please see below the stack trace. i think i missed something in a previous post.
05/12/2009 02:23:00 _ + com.sun.faces.lifecycle.Phase doPhase SEVERE: JSF1054: (Phase ID: INVOKE_APPLICATION 5, View ID: /login.xhtml) Exception thrown during phase execution_: javax.faces.event.PhaseEvent[source=com.sun.faces.lifecycle.LifecycleImpl@7d5 05/12/2009 02:23:00 org.ajax4jsf.webapp.BaseXMLFilter doXmlFilter SEVERE: Exception in the filter chain javax.servlet.ServletException: #{identity.login}: java.lang.IllegalArgumentException: Control character in cookie value, consider BASE64 encoding your value at javax.faces.webapp.FacesServlet.service(FacesServlet.java:277) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:83) at org.jboss.seam.web.IdentityFilter.doFilter(IdentityFilter.java:40) at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69) at org.jboss.seam.web.MultipartFilter.doFilter(MultipartFilter.java:90) at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69) at org.jboss.seam.web.ExceptionFilter.doFilter(ExceptionFilter.java:64) at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69) at org.jboss.seam.web.RedirectFilter.doFilter(RedirectFilter.java:45) at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69) at org.ajax4jsf.webapp.BaseXMLFilter.doXmlFilter(BaseXMLFilter.java:178) at org.ajax4jsf.webapp.BaseFilter.handleRequest(BaseFilter.java:290) at org.ajax4jsf.webapp.BaseFilter.processUploadsAndHandleRequest(BaseFilter.java:390) at org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:517) at org.jboss.seam.web.Ajax4jsfFilter.doFilter(Ajax4jsfFilter.java:56) at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69) at org.jboss.seam.servlet.SeamFilter.doFilter(SeamFilter.java:158) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293) at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:849) at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583) at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:454) at java.lang.Thread.run(Thread.java:595) Caused by: javax.faces.FacesException: #{identity.login}: java.lang.IllegalArgumentException: Control character in cookie value, consider BASE64 encoding your value at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:118) at javax.faces.component.UICommand.broadcast(UICommand.java:387) at org.ajax4jsf.component.AjaxViewRoot.processEvents(AjaxViewRoot.java:321) at org.ajax4jsf.component.AjaxViewRoot.broadcastEvents(AjaxViewRoot.java:296) at org.ajax4jsf.component.AjaxViewRoot.processPhase(AjaxViewRoot.java:253) at org.ajax4jsf.component.AjaxViewRoot.processApplication(AjaxViewRoot.java:466) at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:82) at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:100) at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118) at javax.faces.webapp.FacesServlet.service(FacesServlet.java:265) ... 30 more Caused by: javax.faces.el.EvaluationException: java.lang.IllegalArgumentException: Control character in cookie value, consider BASE64 encoding your value at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:102) at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102) ... 39 more Caused by: java.lang.IllegalArgumentException: Control character in cookie value, consider BASE64 encoding your value at org.apache.tomcat.util.http.ServerCookie.maybeQuote2(ServerCookie.java:396) at org.apache.tomcat.util.http.ServerCookie.maybeQuote2(ServerCookie.java:389) at org.apache.tomcat.util.http.ServerCookie.appendCookieValue(ServerCookie.java:293) at org.apache.catalina.connector.Response.addCookieInternal(Response.java:1010) at org.apache.catalina.connector.Response.addCookieInternal(Response.java:979) at org.apache.catalina.connector.Response.addCookie(Response.java:967) at org.apache.catalina.connector.ResponseFacade.addCookie(ResponseFacade.java:343) at javax.servlet.http.HttpServletResponseWrapper.addCookie(HttpServletResponseWrapper.java:58) at org.ajax4jsf.webapp.FilterServletResponseWrapper.addCookie(FilterServletResponseWrapper.java:627) at javax.servlet.http.HttpServletResponseWrapper.addCookie(HttpServletResponseWrapper.java:58) at org.jboss.seam.faces.Selector.setCookieValueIfEnabled(Selector.java:119) at org.jboss.seam.security.RememberMe$UsernameSelector.setCookieValueIfEnabled(RememberMe.java:70) at org.jboss.seam.security.RememberMe.postAuthenticate(RememberMe.java:388) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:585) at org.jboss.seam.util.Reflections.invoke(Reflections.java:22) at org.jboss.seam.util.Reflections.invokeAndWrap(Reflections.java:144) at org.jboss.seam.Component.callComponentMethod(Component.java:2253) at org.jboss.seam.core.Events.raiseEvent(Events.java:85) at org.jboss.seam.security.Identity.postAuthenticate(Identity.java:397) at org.jboss.seam.security.Identity.authenticate(Identity.java:345) at org.jboss.seam.security.Identity.authenticate(Identity.java:332) at org.jboss.seam.security.Identity.login(Identity.java:259) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:585) at org.jboss.el.util.ReflectionUtil.invokeMethod(ReflectionUtil.java:335) at org.jboss.el.util.ReflectionUtil.invokeMethod(ReflectionUtil.java:348) at org.jboss.el.parser.AstPropertySuffix.invoke(AstPropertySuffix.java:58) at org.jboss.el.parser.AstValue.invoke(AstValue.java:96) at org.jboss.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:276) at com.sun.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:68) at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:88) ... 40 more
Thanks!
-
23. Re: Advance authentication
kapitanpetko Dec 5, 2009 5:40 AM (in response to itays100)Your best bet is to report this with Tomcat. You could also get the source for org.apache.tomcat.util.http.ServerCookie.maybeQuote2 and find out what is wrong, so you can work around it, if possible. Good luck.
-
24. Re: Advance authentication
itays100 Dec 7, 2009 9:43 AM (in response to itays100)That exactly what i did. They came with some idea but i'm not sure what i need to change.
Please take a look and tell me if you can suggest solution for this.Mark Thomas wrote: itay sahar wrote: Caused by: java.lang.IllegalArgumentException: Control character in cookie value, consider BASE64 encoding your value at org.apache.tomcat.util.http.ServerCookie.maybeQuote2(ServerCookie.java:396) To cause this, there must be a character in the value with an ASCII code of less than 0x20 or greater or equal to 0x7f and is not 0x09. You need to fix that first. Then you'll need to worry about Base64 using '=' in cookie values. The value needs to be quoted for this to work. Tomcat will do this automatically if necessary. Mark above is talking about the output value of the Base64 encoder which you are using, and which you then feed to the response.addCookie(cookie) method. It is not clear (to me) where the used Base64.encodeBytes() method comes from. But wherever it comes from, it should encode any input series of bytes according to http://tools.ietf.org/html/rfc3548#section-3 which cannot produce "control characters". Except that some Base64 encoders, in some cases, will "wrap" the output string at 76 bytes, by inserting a CR/LF pair, which are both "control characters". (Note that the output string of Base64 is longer than the input string, since it encodes 3 consecutive input bytes into 4 output bytes.) My guess is that this is what happens here, and that could trigger the exception above. Maybe this Base64.encodeBytes() method has an optional argument which would tell it to not wrap the output value ? Note also that with the code you were showing, the control character(s) could presumably be also in "cookiePath". Why do you not log the cookie value, just before you call setCookieValueIfEnabled(String value) ?
Thanks!
-
25. Re: Advance authentication
kapitanpetko Dec 7, 2009 10:12 AM (in response to itays100)Send them the values that produce an error to get this sorted out. As for the CR/LF, you are indeed close to 76 chasr, so try this in encodeToken (override RememberMe):
... return Base64.encodeBytes(sb.toString().getBytes(), Base64.DONT_BREAK_LINES);
-
26. Re: Advance authentication
itays100 Dec 7, 2009 9:10 PM (in response to itays100)No, you are fine :-)
I extended RememberMe and add your fix and it works like a charm)!
Two more questions:1. Do you know about any problem i should encounter ?
2. I know seamRememberMe
has two modes:1. Remember only the username.
2. Auto login.I currently use the second (As you may know) but do you know how
to use the first choise ?
Thanks!
-
27. Re: Advance authentication
kapitanpetko Dec 8, 2009 2:14 AM (in response to itays100)
Itay Sahar wrote on Dec 07, 2009 21:10:
I extended RememberMe and add your fix and it works like a charm)!Nice to hear. So I was wrong and this is a bug in Seam (Base64 encoding inserts newlines after 76 chars, that breaks cookies). You should report it in JIRA. And you should contact the Tomcat guys, so that they can close the issue.
Two more questions:
1. Do you know about any problem i should encounter ?No. Search the forum if you do :)
2. I know seamRememberMe
has two modes:
1. Remember only the username.
2. Auto login.
I currently use the second (As you may know) but do you know how
to use the first choise ?I haven't actually used it, but AFAIK, there is a switch for that :) Check the docs. Also be aware, that 2. is not very secure, there is a big fat warning in the docs. Again, go over those.
-
28. Re: Advance authentication
shane.bryzak Dec 8, 2009 2:42 AM (in response to itays100)I've fixed the Base64 encoding issue in SVN.
-
29. Re: Advance authentication
marcgemis Dec 11, 2009 4:50 PM (in response to itays100)A related problem:
I tried to use an email as username and use the usernameOnly-mode. The cookie gets properly saved (verified in browser cookies window). Howver, the class org.apache.tomcat.util.http.Cookies regards the '@'-symbol as a separator and therefore reads only part of the cookie.
I guess that I have to extend RememberMe to encode/decode the username as this functionality is not supported by the current implementation (2.2.0.GA)