By: Sylvain BONNEFON user 02 Jun 2021 at 10:30 a.m. CDT

9 Responses
Sylvain BONNEFON gravatar
Hello, We would like to send a live recorded audio file to our gluu server to analyse this and make our authentication logic. Everything is working well **if** we select an audio file with a JSF <h:inputFile> and send it with submit btn. But what we need is not selected a file but created it from user microphone. We succefuly created the audio file blob with MediaAudio recorder. But we don't know how to use JSF to send this file to the backend. What we commonly do is to append this blob to a formData content created from the html form. But here I don't know how to set my xhr request action to #{authenticator.authenticate}. this doesn't seems to be received but the python script: form.addEventListener("click", function(event){ event.preventDefault() }); var formData = new FormData(form); formData.append('loginForm:loginVoice', _voice.data); var url = form.action; var xhr = new XMLHttpRequest(); xhr.addEventListener('load', function(event){ console.log('data sent.'); }) xhr.addEventListener('error', function(event) { alert('Request failed.'); }); xhr.open('POST', '#{authenticator.authenticate}') //also tried with form.action aka https://gluu.pre.whispeak.io/oxauth/whispeak_login.htm, without success xhr.send(formData); I didn't find any integration example with this process maybe could you direct me to a solution. I also thought about translating my blob to a base64 string but I would prefer to not do that.

By Madhumita Subramaniam staff 08 Jun 2021 at 1:08 a.m. CDT

Madhumita Subramaniam gravatar
Hi Sylviann, Use f:ajax - ``` <h:commandButton id="saveFile" onclick="initNewRequest()" value="Save file" > <f:ajax execute="@form" listener="#{authenticator.authenticate()}" render="@form messages" /> </h:commandButton> ``` In the javascript function which gets called onclick ``` function initNewRequest() { // stay on the same page window.location = window.location.href.split(“?”)[0]; // you can append the blob here } ``` In the <f:ajax> tag, * execute="name" – By this assignment, the form component which has id "name" will be sent to the server for processing. In case of multiple components, it is required to separate the ids with the space in between. * render="output" - Subsequent to the Ajax request this will refresh the component which has id "output". * Here after completion of the Ajax request <h:outputText> component will be refreshed. I hope this helps you Have a good day!

By Sylvain BONNEFON user 08 Jun 2021 at 10:40 a.m. CDT

Sylvain BONNEFON gravatar
Hi madhu, My problem is that I want to send some data that are programmaticaly generated and that are not in a form component

By Yuriy Movchan staff 21 Jun 2021 at 11:42 a.m. CDT

Yuriy Movchan gravatar
Hi Sylviann, Can you try to POST data to `#{request.contextPath}/postlogin.htm` instead of `'#{authenticator.authenticate}'` Please share screenshot with reqest/responses from browser as well. Regards, Yuriy

By Sylvain BONNEFON user 22 Jun 2021 at 12:47 p.m. CDT

Sylvain BONNEFON gravatar
Hello Yuriy, Thank you for this answer I tested this but I doesn't receive the data server side. I overwrote the submit with that : ``` this.submit = () => { var spinner = document.getElementById('spinner'); spinner.classList.add("loader"); form = document.getElementById('loginForm'); form.addEventListener("click", function(event){ event.preventDefault() }); var formData = new FormData(form); formData.append('loginForm:methodTab:loginVoice2', _voice.data); for (var data of formData.entries()) { console.log(data[0]+ ': ' + data[1]); } // to send request with the new FormData var xhr = new XMLHttpRequest(); xhr.addEventListener('load', function(event){ console.log('data sent.'); }) xhr.addEventListener('error', function(event) { alert('Request failed.'); }); var url = form.action; // cf. point 1 after xhr.open('POST',url) xhr.setRequestHeader("Content-Type", "multipart/form-data");// Error without this line, and no data server side with this line so... xhr.send(formData); } ``` 1 - this value is set in windows.onload with -> form.action = window.location.protocol + '//' + window.location.hostname + "#{request.contextPath}/postlogin.htm"; because i wasn't able to interprete js tempalte in an independant js file. 2 - After submit my python script is well triggered if I manualy set Content-Type in header with JS but both requestParameters and request.getParts() are empty. In an other hand, if I don't set Content-Type, the request look fine ``` Request URL: https://gluu-scw-docker.pre.whispeak.io/oxauth/postlogin.htm Request Method: POST Status Code: 200 OK Remote Address: 163.172.168.51:443 Referrer Policy: strict-origin-when-cross-origin ________ Connection: keep-alive Content-Length: 68 Content-Type: text/html;charset=utf-8 Date: Tue, 22 Jun 2021 17:36:36 GMT Expires: Thu, 01 Jan 1970 00:00:00 GMT Server: nginx Set-Cookie: csfcfc=mxV39C%2BCyo9pe2bNDyXi06N535qVCFw%3D; Path=/oxauth; Secure; HttpOnly Strict-Transport-Security: max-age=31536000; includeSubDomains X-Content-Type-Options: nosniff X-Xss-Protection: 1; mode=block _______ Accept: */* Accept-Encoding: gzip, deflate, br Accept-Language: fr-FR,fr;q=0.9,en-GB;q=0.8,en-US;q=0.7,en;q=0.6 Cache-Control: no-cache Connection: keep-alive Content-Length: 28119 Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryLpFjXXJ0BrRWcXBa Cookie: rp_origin_id=https://gluu-scw-docker.pre.whispeak.io/identity/authcode.htm; JSESSIONID=node0q3yq23lrqaknk3545jy0phge57.node0; csfcfc=79dlaBFzp95oTTq5I64vgTkflrrmpZc%3D; org.gluu.i18n.Locale=fr; _hjid=00f29872-3df4-419e-a97d-83ea18971dc6; _ga=GA1.2.335482490.1624289661; _ga_YRRDMQSH1G=GS1.1.1624288511.13.1.1624289943.0; current_sessions=["6cf9fac1-ac27-4284-9412-9130ce5d7866"]; session_id=330947c0-ec66-4443-82b1-1d996b4960d6; session_state=d0204d3817a4aa34852d20faea85c794fe53399985ef2157008f51e34adb9b57.71b3d572-9f1e-43d4-a1f3-eac26d3d406f; opbs=73db82e2-5fb7-4864-98ee-50e40e6417b0 Host: gluu-scw-docker.pre.whispeak.io Origin: https://gluu-scw-docker.pre.whispeak.io Pragma: no-cache Referer: https://gluu-scw-docker.pre.whispeak.io/oxauth/authorize.htm?scope=openid+profile+email+user_name&acr_values=whispeak&response_type=code&redirect_uri=https%3A%2F%2Fgluu-scw-docker.pre.whispeak.io%2Fidentity%2Fauthcode.htm&state=20f3db9a-b3ea-472c-9ff7-23a2e21cb989&nonce=ee4ac051-fd02-4d6f-aaf0-6cfd4810f17b&client_id=1001.8079a888-c602-42ca-aed3-2ca73f2665bf sec-ch-ua: "Chromium";v="91", " Not;A Brand";v="99" sec-ch-ua-mobile: ?0 Sec-Fetch-Dest: empty Sec-Fetch-Mode: cors Sec-Fetch-Site: same-origin User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36 _______ loginForm: loginForm loginForm:username: theusername loginForm:methodTab:voiceBase64: GkXfo59ChoEBQveBAULygQRC84EIQoKEd2VibUKHgQRChYECGFOAZwH/////////FUmpZpkq17GDD0JATYCGQ2hyb21lV0GGQ2hyb21lFlSua7+uvdeBAXPFh8aJgY6kPBuDg[...]HF6J4P0viK+B9GTCLNvZ3JgOwfJYBwJ8qQUTdNbmNo+BIAdypuvOQfg++rHwb0SS2PGwv5+H6imKFDFEBew9gorJSNWPpn7FjCFRoBlEc13Cvcqf3wwB2bHWjZC07C3V55ZN8S13LqHFNUCBt1v3jHgLoBKwQYBENOjQJmSLNkDag== loginForm:methodTab:loginVoice: (binary) loginForm:methodTab_activeIndex: 0 loginForm:platform: {"description":"Chrome 91.0.4472.114 on Linux 64-bit","layout":"Blink","manufacturer":null,"name":"Chrome","prerelease":null,"product":null,"ua":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36","version":"91.0","os":{"architecture":64,"family":"Linux","version":null},"isMobile":false} javax.faces.ViewState: stateless loginForm:methodTab:loginVoice2: (binary) ``` But I have an error with python script : ``` 2021-06-22 17:36:24,605 INFO [qtp1422222071-3300] [org.gluu.service.PythonService$PythonLoggerOutputStream] (PythonService.java:243) - Use pwd None 2021-06-22 17:36:24,611 INFO [qtp1422222071-3300] [org.gluu.service.PythonService$PythonLoggerOutputStream] (PythonService.java:243) - None 2021-06-22 17:36:24,612 ERROR [qtp1422222071-3300] [org.gluu.oxauth.service.external.ExternalAuthenticationService] (ExternalAuthenticationService.java:212) - javax.servlet.ServletException: javax.servlet.ServletException: Unsupported Content-Type [null], expected [multipart/form-data] org.python.core.PyException: javax.servlet.ServletException: javax.servlet.ServletException: Unsupported Content-Type [null], expected [multipart/form-data] ``` And RequestParameter is always empty (None at second logs line) This logs are refering to this script snipet : ``` def authenticate(self, configurationAttributes, requestParameters, step): if LOG: self.__print_method(self.authenticate) logged_in = False print "Whispeak. Authenticate for step %d" % step self.__clearMessage() print "Use pwd %s" % (self.cache.get("USE_PWD")) if (step == 1 and not self.cache.get("USE_PWD")): facesContext = CdiUtil.bean(FacesContext) context = facesContext.getCurrentInstance().getExternalContext() request = context.getRequest() login_voice64 = requestParameters.get("loginForm:methodTab:voiceBase64") print login_voice64 login_voice = request.getPart("loginForm:methodTab:loginVoice2") print login_voice for part in request.getParts(): print part [...] ``` 3 - Also whent the previous part will work I am not sure where to redirect after submit, I was thinking to redirect to "#{authorizeAction.redirectUri}", but I am not sure about the beharviour if authentication fail, or if I need a second auth step etc.

By Sylvain BONNEFON user 22 Jun 2021 at 1:13 p.m. CDT

Sylvain BONNEFON gravatar
1- At the end I used the original form.action to perform the request and send the file data and it seems to work now. It did not work with #{request.contextPath}/postlogin.htm 2 - I always don't know wich url to set for redirection after submit form. // -> EDIT: I redirect to current location and it seems to work 3- The error: ```Unsupported Content-Type [null], expected [multipart/form-data]``` does not seem to be related but I would like to figure out what is the origin of this and avoid to have this error in logs if you can help me. Thanks again

By Sylvain BONNEFON user 24 Jun 2021 at 4:34 a.m. CDT

Sylvain BONNEFON gravatar
Hello, Unlike what I wrote in my previous response, the redirection doesn't work well. It is working only when I use my auth script/page to connect to gluu. When our auth script is used in an other process to use gluu as idp it doesn't redirect to the service that ask the auth to gluu. I tried to used #{identity.getSessionId().getSessionAttributes().get("redirect_uri")} to make this redirection but it doesn't seem to work. ``` this.submit = () => { var spinner = document.getElementById('spinner'); spinner.classList.add("loader"); pwdTab = document.getElementById('loginForm:methodTab:tabPassword') if (pwdTab.getAttribute('aria-hidden') === "false"){ pwd = document.getElementById('loginForm:methodTab:password') pwd.id = 'loginForm:password'; pwd.name = 'loginForm:password'; } form = document.getElementById('loginForm'); var url = form.action var uri = document.getElementById('redirectUri').value // aka #{identity.getSessionId().getSessionAttributes().get("redirect_uri")} form.addEventListener("click", function(event){ event.preventDefault() }); var formData = new FormData(form); formData.append('loginForm:methodTab:loginVoice', _voice.data); // to send request with the new FormData var xhr = new XMLHttpRequest(); xhr.addEventListener('load', function(event){ console.log('data sent.'); window.location = uri; }) xhr.addEventListener('error', function(event) { alert('Request failed.'); }); xhr.open('POST', url, false); xhr.send(formData); } ``` // the error at point 3 about content-type does not appear anymore So the real issue point for this tiicket is about the redirection after authenticate succed now BR & thanks

By Sylvain BONNEFON user 28 Jun 2021 at 1:54 a.m. CDT

Sylvain BONNEFON gravatar
Good morning, To clarify my question: could you give me the good way to manualy redirect to the Client redirection Uri please ? HAve a nice day, SB

By Madhumita Subramaniam staff 28 Jun 2021 at 8:02 a.m. CDT

Madhumita Subramaniam gravatar
Hi Sylvian, You can obtain the redirect_uri ``` #{identity.sessionId.sessionAttributes['redirect_uri'])} ``` Once the authenticate() method of the authentication is invoked, the flow is not really in your control, it moves to the next authentication step, or completes it by marking the authentication as success / failure. Where are you introducing your redirection to the client redirect_uri. It should take the normal flow because Gluu does many things in the background like handling the session and marking the authentication as completed etc which are much needed.

By Sylvain BONNEFON user 30 Jun 2021 at 3:44 a.m. CDT

Sylvain BONNEFON gravatar
Thank you Madhu, This doesn't work to redirect to the client. We are going to use the Post of file using convertion to base64 until we can find a solution to overwrite the form button action correctly.