B4J Question Return from browser to B4J app

josejad

Expert
Licensed User
Longtime User
Hi:

I am trying to make this example work in B4J.
The app opens the browser, and after login, it doesn't return to the B4J app.
You can set the return_uri in Microsoft Authentication page, I've tried several of them, like "https://login.microsoftonline.com/common/oauth2/nativeclient" or the one which Erel's use in their Google oAuth2 sample: "http://127.0.0.1:51067", but they doesn't work.



After login, the browser goes to the indicated uri with the right params (code, etc...) The browser returns:
B4X:
http://127.0.0.1:51067/?code=1.AYEAyJZMEN0ipkazjJYkmiPT3l.........&state=12345&session_state=96eb959e-5543-4f86-a904-461080b0c3a8")
but the B4J app doesn't get any response.

Thanks
 
Last edited:

josejad

Expert
Licensed User
Longtime User
Well, looking at the code which gets the response, probably the Google oAuth2 response includes the word "host" at some point.
I've using log to get the response, but it comes empty from browser after login:
B4X:
 Log("Response: " & Response.ToString)
Result->Response:

B4X:
Private Sub PrepareServer
    Log("Prepare server")
    If server.IsInitialized Then server.Close
    If astream.IsInitialized Then astream.Close
    Do While True
        Try
            server.Initialize(port, "server")
            server.Listen
            Exit
        Catch
            port = port + 1
            Log(LastException)
        End Try
    Loop
    Wait For server_NewConnection (Successful As Boolean, NewSocket As Socket)
    If Successful Then
        astream.Initialize(NewSocket.InputStream, NewSocket.OutputStream, "astream")
        Dim Response As StringBuilder
        Response.Initialize
        Log("Response: " & Response.ToString)
        Do While Response.ToString.Contains("Host:") = False
            Wait For AStream_NewData (Buffer() As Byte)
            Response.Append(BytesToString(Buffer, 0, Buffer.Length, "UTF8"))
        Loop
        astream.Write(("HTTP/1.0 200" & Chr(13) & Chr(10)).GetBytes("UTF8"))
        Sleep(50)
        astream.Close
        server.Close
        ParseBrowserUrl(Regex.Split2("$",Regex.MULTILINE, Response.ToString)(0))
    End If
    
End Sub
 
Upvote 0

DonManfred

Expert
Licensed User
Longtime User
but the B4J app doesn't get any response.
Check Erels OAuth-Class


It is - internally - setting up a webserver listening on a specific url.

Guess you have to adapt the class to do the same.
 
Upvote 0

josejad

Expert
Licensed User
Longtime User
Thanks Manfred... You're right... checking the code and I think I'm close to get it working!!
 
Upvote 0

josejad

Expert
Licensed User
Longtime User
I think as long as you get the return URL then you can parse the token (code) and use it in your client app
Yes, that's the problem.

The original sample from Erel, uses this sub, but it doesn't work for me

B4X:
Private Sub GetTokenFromAuthorizationCode (Code As String)
    Log("Getting access token from authorization code..." & Code)
    Dim j As HttpJob
    j.Initialize("", Me)
    '$"https://login.microsoftonline.com/${tenant}/oauth2/v2.0/token"$, sb.ToString.GetBytes("UTF8")
    Dim postString As String = $"$token"${Code}"$
    postString = AddClientSecret(postString)
    j.PostString($"https://login.microsoftonline.com/${mTenant}/oauth2/v2.0/"$, postString)
       
    Wait For (j) JobDone(j As HttpJob)
    'Log("Response: " & j.poststring)
    If j.Success Then
        Log("Success")
        TokenInformationFromResponse(j.GetString)
    Else
        Log("else")
        ResetToken
        RaiseEvent(False)
    End If
    j.Release
End Sub

So I get the token from this sub, it works with B4A, but here seems the TaskId = 1 doesn't run...

B4X:
'Not in Erel's sample. Added from https://www.b4x.com/android/forum/threads/logging-in-to-ms-365.148816/
Sub GetTokenImpl(authCode As String) As ResumableSub 'añadido de MSLOGIN
    Log("GetTokenImpl: " & authCode)
    Dim params As Map
    params.Initialize
    params.Put("client_id", mClientId)
    params.Put("code", authCode)
    params.Put("redirect_uri", redirectURI)
    params.Put("grant_type", "authorization_code")

    Dim sb As StringBuilder
    sb.Initialize
    For Each key As String In params.Keys
        sb.Append(key).Append("=").Append(params.Get(key)).Append("&")
    Next
    sb.Remove(sb.Length - 1, sb.Length) ' Remove the last "&"
    Dim hc As OkHttpClient
    hc.Initialize("hc")
    Dim req As OkHttpRequest
    req.InitializePost2($"https://login.microsoftonline.com/${mTenant}/oauth2/v2.0/token"$, sb.ToString.GetBytes("UTF8"))
    hc.Execute(req, 1)
    Log("Llega aquí")
    Wait For hc_ResponseSuccess (Response As OkHttpResponse, TaskId As Int)
    Log("Response: " & Response.GetHeaders)
    If TaskId = 1 Then
        Log("TaksId = 1") '<------ The sub doesn't reach this line
        Response.GetAsynchronously("response", File.OpenOutput(xui.DefaultFolder, "response.txt", False), True, TaskId)
        Wait For response_StreamFinish (Success As Boolean, TaskId As Int)
        If Success Then
            Dim parser As JSONParser
            parser.Initialize(File.ReadString(xui.DefaultFolder, "response.txt"))
            TokenInformationFromResponse(File.ReadString(xui.DefaultFolder, "response.txt"))
        Else
            Log("Error: " & LastException.Message)
        ResetToken
        RaiseEvent(False)
        End If

        Return Null
    End If
    Return Null
End Sub
 
Last edited:
Upvote 0

josejad

Expert
Licensed User
Longtime User
Are you sure this is correct ?
No, checking my working sub, I'm modifing to something like:

B4X:
    Dim postString As String = $"client_id=${mClientId}&code=${Code}&redirect_uri=${GetRedirectUri}&grant_type=authorizacion_code"$
    postString = AddClientSecret(postString)
    Log("Poststring: " & postString)
    j.PostString($"https://login.microsoftonline.com/${mTenant}/oauth2/v2.0/"$, postString)
 
Upvote 0

aeric

Expert
Licensed User
Longtime User
i don´t think this is correct. Should it not be authorization_code ?
I saw that too but I think jose used the map to construct the url.

B4X:
    Dim params As Map
    params.Initialize
    params.Put("client_id", mClientId)
    params.Put("code", authCode)
    params.Put("redirect_uri", redirectURI)
    params.Put("grant_type", "authorization_code")
 
Upvote 0
Cookies are required to use this site. You must accept them to continue using the site. Learn more…