<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body><div>If you don't have requirements that your certificate authenticator be proprietary, might I suggest that you open-source it? I think this kind of authentication may not be an uncommon use case, particularly with the Internet of Things beginning to take off.</div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div>On Thu, Jul 7, 2016, at 10:53 AM, Filipe Lautert wrote:<br></div>
<blockquote type="cite"><div dir="ltr"><div>Hello<br></div>
<div>&nbsp;</div>
<div>short story: is there a way to get the request body sent from the client inside an<span style="line-height:1.5;">&nbsp;Authenticator (my class implements Authenticator , unsing method @Override authenticate(context)) ? I'm trying with&nbsp;</span><span style="line-height:18px;">context.getHttpRequest().getInputStream() but it is empty.</span><br></div>
<div><div>&nbsp;</div>
<div>Full story:<br></div>
<div>I'm trying to build a Keycloak authenticator that reads a client certificate and uses it to validate the user, using as a base the SecretQuestionAuthenticator example . The client certificate is a hard token that is read by Firefox. To handle the certificate read part I'm usng Apache mod ssl, with the below relevant configuration:<br></div>
<div>&nbsp;</div>
<div><div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;overflow-y:visible;overflow-x:visible;clear:both;direction:ltr;line-height:normal;"><p style="margin: 0px; padding: 0px; word-wrap: break-word; vertical-align: baseline;" lang="EN-US"><span class="highlight" style="background-color:transparent"><span class="colour" style="color:windowtext"><span class="highlight" style="background-color:transparent"><span class="colour" style="color:windowtext"><span style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:transparent;">SSLEngine</span><span class="highlight" style="background-color:inherit"><span>&nbsp;</span>on</span></span></span><span class="highlight" style="background-color:transparent"><span class="colour" style="color:windowtext">&nbsp;</span></span></span></span><br></p></div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;overflow-y:visible;overflow-x:visible;clear:both;direction:ltr;line-height:normal;"><p style="margin: 0px; padding: 0px; word-wrap: break-word; vertical-align: baseline;" lang="EN-US"><span class="highlight" style="background-color:transparent"><span class="colour" style="color:windowtext"><span class="colour" style="color:windowtext"><span style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:transparent;">SSLProxyEngine</span><span class="highlight" style="background-color:inherit"><span>&nbsp;</span>on</span></span><span style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;line-height:18px;">&nbsp;</span></span></span><br></p></div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;overflow-y:visible;overflow-x:visible;clear:both;direction:ltr;line-height:normal;"><p style="margin: 0px; padding: 0px; word-wrap: break-word; vertical-align: baseline;" lang="EN-US"><span class="highlight" style="background-color:transparent"><span class="colour" style="color:windowtext"><span class="colour" style="color:windowtext"><span class="highlight" style="background-color:inherit">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;</span><span style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:transparent;">LocationMatch</span><span class="highlight" style="background-color:inherit"><span>&nbsp;</span>"/</span><span style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:transparent;">auth</span><span class="highlight" style="background-color:inherit">"&gt;</span></span><span style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;line-height:18px;">&nbsp;</span></span></span><br></p></div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;overflow-y:visible;overflow-x:visible;clear:both;direction:ltr;line-height:normal;"><p style="margin: 0px; padding: 0px; word-wrap: break-word; vertical-align: baseline;" lang="EN-US"><span class="highlight" style="background-color:transparent"><span class="colour" style="color:windowtext"><span class="colour" style="color:windowtext"><span class="highlight" style="background-color:inherit">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span>&nbsp;</span></span><span style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:transparent;">ProxyPass</span><span class="highlight" style="background-color:inherit"><span>&nbsp;</span>ajp://localhost:8010/auth</span></span><span style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;line-height:18px;">&nbsp;</span></span></span><br></p></div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;overflow-y:visible;overflow-x:visible;clear:both;direction:ltr;line-height:normal;"><p style="margin: 0px; padding: 0px; word-wrap: break-word; vertical-align: baseline;" lang="EN-US"><span class="highlight" style="background-color:transparent"><span class="colour" style="color:windowtext"><span class="colour" style="color:windowtext"><span class="highlight" style="background-color:inherit">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span>&nbsp;</span></span><span style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:transparent;">ProxyPassReverse</span><span class="highlight" style="background-color:inherit"><span>&nbsp;</span>ajp://localhost:8010/auth</span></span><span style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;line-height:18px;">&nbsp;</span></span></span><br></p></div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;overflow-y:visible;overflow-x:visible;clear:both;direction:ltr;"><p style="line-height: normal; margin: 0px; padding: 0px; word-wrap: break-word; vertical-align: baseline;" lang="EN-US"><span class="highlight" style="background-color:transparent"><span class="colour" style="color:windowtext"><span class="colour" style="color:windowtext"><span class="highlight" style="background-color:inherit">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;/</span><span style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:transparent;">LocationMatch</span><span class="highlight" style="background-color:inherit">&gt;</span></span><span style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;line-height:18px;">&nbsp;</span></span></span><br></p><p style="line-height: normal; margin: 0px; padding: 0px; word-wrap: break-word; vertical-align: baseline;" lang="EN-US"><span class="highlight" style="background-color:transparent"><span class="colour" style="color:windowtext"><span style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;line-height:18px;"><span class="colour" style="color:windowtext"><span style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:transparent;">SSLOptions</span><span class="highlight" style="background-color:inherit"><span>&nbsp;</span>+</span><span style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:transparent;">StdEnvVars</span><span class="highlight" style="background-color:inherit"><span>&nbsp;</span>+</span><span style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:transparent;">ExportCertData</span></span><span style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;">&nbsp;</span></span></span></span><br></p><p style="line-height: normal; margin: 0px; padding: 0px; word-wrap: break-word; vertical-align: baseline;" lang="EN-US"><span class="highlight" style="background-color:transparent"><span class="colour" style="color:windowtext"><span style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;line-height:18px;"><span style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;">... etc</span></span></span></span><br></p><p style="line-height: normal; margin: 0px; padding: 0px; word-wrap: break-word; vertical-align: baseline;" lang="EN-US"><span class="highlight" style="background-color:transparent"><span class="colour" style="color:windowtext"><span style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;line-height:18px;"><span style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;"></span></span></span></span><br></p><p style="line-height: normal; margin: 0px; padding: 0px; word-wrap: break-word; vertical-align: baseline;" lang="EN-US"><span class="highlight" style="background-color:transparent"><span class="colour" style="color:windowtext"><span style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;line-height:18px;"><span style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;">Looking at a tcpdump/wireshark on port 8010, I can see that the client certificate is sent on the request body to Keycloak.</span></span></span></span><br></p><p style="line-height: normal; margin: 0px; padding: 0px; word-wrap: break-word; vertical-align: baseline;" lang="EN-US"><span class="highlight" style="background-color:transparent"><span class="colour" style="color:windowtext"><span style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;line-height:18px;"><span style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;"></span></span></span></span><br></p><p style="margin: 0px; padding: 0px; word-wrap: break-word; vertical-align: baseline;" lang="EN-US"><span class="highlight" style="background-color:transparent"><span class="colour" style="color:windowtext"><span style="line-height:18px;">So far fine, Apache validates the certificate, extracts it and send to Keycloak. The problem is that I'm unable to read the request body inside my authenticator class as&nbsp;</span></span><span class="colour" style="color:windowtext">context.getHttpRequest().getInputStream() is empty, and as the body is the raw certificate the method&nbsp;</span><span style="line-height:18px;">context.getHttpRequest().getFormParameters() method won't return me anything.</span></span><br></p><p style="margin: 0px; padding: 0px; word-wrap: break-word; vertical-align: baseline;" lang="EN-US"><span class="highlight" style="background-color:transparent"><span class="colour" style="color:windowtext"><span style="line-height:18px;"></span></span></span><br></p><p style="margin: 0px; padding: 0px; word-wrap: break-word; vertical-align: baseline;" lang="EN-US"><span class="highlight" style="background-color:transparent"><span style="line-height:18px;">public class SecretQuestionAuthenticator implements Authenticator {</span></span><br></p><p style="margin: 0px; padding: 0px; word-wrap: break-word; vertical-align: baseline;" lang="EN-US"><span class="highlight" style="background-color:transparent"><span style="line-height:18px;"><span style="white-space:pre;"></span>@Override</span></span><br></p><p style="margin: 0px; padding: 0px; word-wrap: break-word; vertical-align: baseline;" lang="EN-US"><span class="highlight" style="background-color:transparent"><span style="line-height:18px;"><span style="white-space:pre;"></span>public void authenticate(AuthenticationFlowContext context) {</span></span><br></p><p style="margin: 0px; padding: 0px; word-wrap: break-word; vertical-align: baseline;" lang="EN-US"><span class="highlight" style="background-color:transparent"><span style="line-height:18px;"><span style="white-space:pre;"></span></span><span style="line-height:18px;">System.out.println(</span><span style="line-height:18px;">context.getHttpRequest().getInputStream().available()); // prints 0</span><span class="highlight" style="background-color:transparent"> </span><span class="highlight" style="background-color:transparent">System.out.println(getStringFromInputStream(context.getHttpRequest().getInputStream())); //empty :(</span></span><br></p><p style="margin: 0px; padding: 0px; word-wrap: break-word; vertical-align: baseline;" lang="EN-US"><span class="highlight" style="background-color:transparent"></span><br></p><p style="margin: 0px; padding: 0px; word-wrap: break-word; vertical-align: baseline;" lang="EN-US"><span class="highlight" style="background-color:transparent"></span><br></p><p style="margin: 0px; padding: 0px; word-wrap: break-word; vertical-align: baseline;" lang="EN-US"><span class="highlight" style="background-color:transparent"><span style="line-height:18px;"></span></span><br></p><p style="margin: 0px; padding: 0px; word-wrap: break-word; vertical-align: baseline;" lang="EN-US"><span class="highlight" style="background-color:transparent"><span style="line-height:18px;">Any ideas of how I can get it to work?</span></span><br></p><p style="margin: 0px; padding: 0px; word-wrap: break-word; vertical-align: baseline;" lang="EN-US"><span class="highlight" style="background-color:transparent"><span style="line-height:18px;"></span></span><br></p><p style="margin: 0px; padding: 0px; word-wrap: break-word; vertical-align: baseline;" lang="EN-US"><span class="highlight" style="background-color:transparent"><span style="line-height:18px;">Thanks</span></span><br></p><p style="margin: 0px; padding: 0px; word-wrap: break-word; vertical-align: baseline;" lang="EN-US"><span class="highlight" style="background-color:transparent"><span style="line-height:18px;"></span></span><br></p><p style="margin: 0px; padding: 0px; word-wrap: break-word; vertical-align: baseline;" lang="EN-US"><span class="highlight" style="background-color:transparent"><span style="line-height:18px;">filipe</span></span><br></p></div>
</div>
</div>
</div>
<div dir="ltr">-- <br></div>
<div><div dir="ltr">filipe lautert<br></div>
</div>
<div><u>_______________________________________________</u><br></div>
<div>keycloak-user mailing list<br></div>
<div><a href="mailto:keycloak-user@lists.jboss.org">keycloak-user@lists.jboss.org</a><br></div>
<div><a href="https://lists.jboss.org/mailman/listinfo/keycloak-user">https://lists.jboss.org/mailman/listinfo/keycloak-user</a><br></div>
</blockquote><div>&nbsp;</div>
<div id="sig3995191"><div class="signature">--<br></div>
<div class="signature">&nbsp; Aikeaguinea<br></div>
<div class="signature">&nbsp; aikeaguinea@xsmail.com<br></div>
<div class="signature">&nbsp;</div>
</div>
<div>&nbsp;</div>
<pre>
-- 
http://www.fastmail.com - Does exactly what it says on the tin
</pre>
</body>
</html>