AzureAD / microsoft-authentication-library-for-java

Microsoft Authentication Library (MSAL) for Java http://aka.ms/aadv2
MIT License
288 stars 145 forks source link

[Bug] java.net.SocketException: Permission denied: connect #778

Closed croccio closed 9 months ago

croccio commented 9 months ago

Library version used

1.14.2

Java version

15

Scenario

PublicClient (AcquireTokenInteractive, AcquireTokenByUsernamePassword)

Is this a new or an existing app?

This is a new app or experiment

Issue description and reproduction steps

After inserting username and password and clicking on "Login" button then on app sidejava.net.SocketException: Permission denied: connect is triggered

Relevant code snippets

val app = PublicClientApplication
                                .builder(PUBLIC_CLIENT_ID)
                                .authority(AUTHORITY)
                                .build()

                            val scopes = setOf(
                                "scope1",
                                "scope2",
                                "scope3"
                            )

                            val parameters = InteractiveRequestParameters
                                .builder(URI("https://localhost"))
                                .scopes(scopes)
                                .build()

                            val result: IAuthenticationResult = app.acquireToken(parameters).join()

Expected behavior

I receive the token

Identity provider

Microsoft Entra ID (Work and School accounts and Personal Microsoft accounts)

Regression

No response

Solution and workarounds

No response

Avery-Dunn commented 9 months ago

Hello @croccio : "Permission denied: connect" seems like it's a networking problem of some sort. Are you running your app behind any proxy/firewall that could deny the connection, or running it on some sort of app server (Tomcat, Wildfly, etc.) that could have it's own network configuration?

Also, that code snippet isn't pure Java. Is it Kotlin? What version of that are you using?

croccio commented 9 months ago

@Avery-Dunn it is kotlin, but in java is the same. The version of kotlin is 1.9.22. The app is a client desktop app, so no app server is used and no proxy/firewall.

Avery-Dunn commented 9 months ago

I haven't been able to reproduce this issue, the interactive flow on MSAL 1.14.2/Java 15 works fine for me. Could we get the stack trace along with the error?

And just to clarify some things:

Other than that, I did just notice that the redirect URL in your code snippet is "https://localhost". Is that just a typo in your code snippet? Because using https should get you an error before the point of entering your username/password.

croccio commented 9 months ago

Yes it's my bad, it is http://localhost on my code

here you are the stacktrace: java.util.concurrent.CompletionException: com.microsoft.aad.msal4j.MsalClientException: java.net.SocketException: Permission denied: connect at com.microsoft.aad.msal4j@1.14.2/com.microsoft.aad.msal4j.AuthenticationResultSupplier.get(AuthenticationResultSupplier.java:103) at com.microsoft.aad.msal4j@1.14.2/com.microsoft.aad.msal4j.AuthenticationResultSupplier.get(AuthenticationResultSupplier.java:18) at java.base/java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1764) at java.base/java.util.concurrent.CompletableFuture$AsyncSupply.exec(CompletableFuture.java:1756) at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:290) at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1016) at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1665) at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1598) at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:183) Caused by: com.microsoft.aad.msal4j.MsalClientException: java.net.SocketException: Permission denied: connect at com.microsoft.aad.msal4j@1.14.2/com.microsoft.aad.msal4j.HttpHelper.executeHttpRequest(HttpHelper.java:56) at com.microsoft.aad.msal4j@1.14.2/com.microsoft.aad.msal4j.AadInstanceDiscoveryProvider.executeRequest(AadInstanceDiscoveryProvider.java:299) at com.microsoft.aad.msal4j@1.14.2/com.microsoft.aad.msal4j.AadInstanceDiscoveryProvider.sendInstanceDiscoveryRequest(AadInstanceDiscoveryProvider.java:249) at com.microsoft.aad.msal4j@1.14.2/com.microsoft.aad.msal4j.AadInstanceDiscoveryProvider.doInstanceDiscoveryAndCache(AadInstanceDiscoveryProvider.java:360) at com.microsoft.aad.msal4j@1.14.2/com.microsoft.aad.msal4j.AadInstanceDiscoveryProvider.getMetadataEntry(AadInstanceDiscoveryProvider.java:108) at com.microsoft.aad.msal4j@1.14.2/com.microsoft.aad.msal4j.AuthenticationResultSupplier.getAuthorityWithPrefNetworkHost(AuthenticationResultSupplier.java:39) at com.microsoft.aad.msal4j@1.14.2/com.microsoft.aad.msal4j.AcquireTokenByAuthorizationGrantSupplier.execute(AcquireTokenByAuthorizationGrantSupplier.java:59) at com.microsoft.aad.msal4j@1.14.2/com.microsoft.aad.msal4j.AcquireTokenByInteractiveFlowSupplier.acquireTokenWithAuthorizationCode(AcquireTokenByInteractiveFlowSupplier.java:270) at com.microsoft.aad.msal4j@1.14.2/com.microsoft.aad.msal4j.AcquireTokenByInteractiveFlowSupplier.execute(AcquireTokenByInteractiveFlowSupplier.java:48) at com.microsoft.aad.msal4j@1.14.2/com.microsoft.aad.msal4j.AuthenticationResultSupplier.get(AuthenticationResultSupplier.java:69) ... 8 more Caused by: java.net.SocketException: Permission denied: connect at java.base/sun.nio.ch.Net.connect0(Native Method) at java.base/sun.nio.ch.Net.connect(Net.java:574) at java.base/sun.nio.ch.Net.connect(Net.java:563) at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:588) at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:333) at java.base/java.net.Socket.connect(Socket.java:648) at java.base/sun.security.ssl.SSLSocketImpl.connect(SSLSocketImpl.java:290) at java.base/sun.net.NetworkClient.doConnect(NetworkClient.java:177) at java.base/sun.net.www.http.HttpClient.openServer(HttpClient.java:474) at java.base/sun.net.www.http.HttpClient.openServer(HttpClient.java:569) at java.base/sun.net.www.protocol.https.HttpsClient.<init>(HttpsClient.java:265) at java.base/sun.net.www.protocol.https.HttpsClient.New(HttpsClient.java:372) at java.base/sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.getNewHttpClient(AbstractDelegateHttpsURLConnection.java:189) at java.base/sun.net.www.protocol.http.HttpURLConnection.plainConnect0(HttpURLConnection.java:1194) at java.base/sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:1082) at java.base/sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:175) at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1600) at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1528) at java.base/java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:527) at java.base/sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:308) at com.microsoft.aad.msal4j@1.14.2/com.microsoft.aad.msal4j.DefaultHttpClient.readResponseFromConnection(DefaultHttpClient.java:110) at com.microsoft.aad.msal4j@1.14.2/com.microsoft.aad.msal4j.DefaultHttpClient.executeHttpGet(DefaultHttpClient.java:52) at com.microsoft.aad.msal4j@1.14.2/com.microsoft.aad.msal4j.DefaultHttpClient.send(DefaultHttpClient.java:40) at com.microsoft.aad.msal4j@1.14.2/com.microsoft.aad.msal4j.HttpHelper.executeHttpRequestWithRetries(HttpHelper.java:99) at com.microsoft.aad.msal4j@1.14.2/com.microsoft.aad.msal4j.HttpHelper.executeHttpRequest(HttpHelper.java:52)

Let me know if you need more info. Thanks!

croccio commented 9 months ago

Could this issue depends by Windows Firewall?

bgavrilMS commented 9 months ago

@Avery-Dunn - can you please point @croccio at the WAM implementation?

@croccio - is your app supposed to run on all operating systems? Does this happen on Mac and Linux? For Windows we recommend not using the system browser, but a Windows component called WAM. For Mac and Linux MSAL will automatically fallback to the system brwoser.

Avery-Dunn commented 9 months ago

As @bgavrilMS mentioned, Web Account Manager (WAM) is another option for logging in users in a desktop app, and here are the docs for it: https://learn.microsoft.com/en-us/entra/msal/java/advanced/using-wam-and-the-msal4jbrokers-package

If your desktop app will only ever have one user logged in (the same one who's logged into the computer it's running on), then it's probably your simplest option: if the broker is enabled and you use the silent flow MSAL should be able to sign in the user without them ever seeing a prompt.

As for Windows firewall, it's a permission connection error so any sort of firewall could be blocking it. You could try disabling it temporarily to see if it works, though I'm not sure what firewall setting could be blocking the redirect.

Other than that, you could try another public client flow (device code, username/password, WAM) to see if you get the same error: if you do it's likely an environment/network issue, if not then it's either an app configuration issue or an issue in MSAL.

croccio commented 9 months ago

Thanks for suggestested these implementations. I tried with broker but as it is not terminal app i have to pass windowHandle property. I passed it but the software block and i have to force close it. I tried also to use the silent flow, but i have to pass an "IAccount". From where i can retrieve it?

In meantime i'll try with another publick client flow.

Avery-Dunn commented 9 months ago

For the broker, yes for UI-based apps you need the correct window handle to act as the parent of the login window that the broker opens, and getting the correct one can be finicky.

As for silent flow (acquireTokenSilently), that is only usable once you make a successful token request and start populating the cache. Once you do, then the AuthenticationResult returned by the acquireToken method will have the relevant account for that token, and the getAccounts method of the PublicClientApplication can be used to get all accounts in the cache.

And finally, if you're trying another public flow just for testing this issue you can check out our samples. If you're still getting the issue even outside of your actual project, then it's much more likely to just be a configuration/environment issue: https://github.com/Azure-Samples/ms-identity-msal-java-samples/tree/main/2-client-side

Avery-Dunn commented 9 months ago

Closing due to inactivity. If you're still having issues or have any other questions, feel free to leave a comment or start a new thread.