77import org .slf4j .LoggerFactory ;
88
99import java .awt .*;
10+ import java .io .File ;
1011import java .io .IOException ;
1112import java .net .URI ;
1213import java .net .URISyntaxException ;
1314import java .net .URL ;
15+ import java .util .Arrays ;
16+ import java .util .List ;
1417import java .util .concurrent .BlockingQueue ;
1518import java .util .concurrent .LinkedBlockingQueue ;
1619import java .util .concurrent .TimeUnit ;
1720
1821class AcquireTokenByInteractiveFlowSupplier extends AuthenticationResultSupplier {
1922
20- private final static Logger LOG = LoggerFactory .getLogger (AcquireTokenByAuthorizationGrantSupplier .class );
23+ private static final Logger LOG = LoggerFactory .getLogger (AcquireTokenByInteractiveFlowSupplier .class );
2124
2225 private PublicClientApplication clientApplication ;
2326 private InteractiveRequest interactiveRequest ;
2427
2528 private BlockingQueue <AuthorizationResult > authorizationResultQueue ;
2629 private HttpListener httpListener ;
2730
31+ /**MSAL tried to open the browser on Linux using the xdg-open, gnome-open, or kfmclient tools, but failed.
32+ Make sure you can open a page using xdg-open tool. See <a href="https://aka.ms/msal-net-os-browser">...</a> for details. */
33+ public static final String LINUX_XDG_OPEN = "linux_xdg_open_failed" ;
34+
35+ public static final String LINUX_OPEN_AS_SUDO_NOT_SUPPORTED = "Unable to open a web page using xdg-open, gnome-open, kfmclient or wslview tools in sudo mode. Please run the process as non-sudo user." ;
36+
2837 AcquireTokenByInteractiveFlowSupplier (PublicClientApplication clientApplication ,
2938 InteractiveRequest request ) {
3039 super (clientApplication , request );
@@ -106,8 +115,38 @@ private void updateRedirectUrl() {
106115 AuthenticationErrorCode .INVALID_REDIRECT_URI );
107116 }
108117 }
118+ private static List <String > getOpenToolsLinux () {
119+ return Arrays .asList ("xdg-open" , "gnome-open" , "kfmclient" , "microsoft-edge" , "wslview" );
120+ }
121+
122+ private static String getExecutablePath (String executable ) {
123+ String pathEnvVar = System .getenv ("PATH" );
124+ if (pathEnvVar != null ) {
125+ String [] paths = pathEnvVar .split (File
126+ .pathSeparator );
127+ for (String basePath : paths ) {
128+ String path = basePath + File .separator + executable ;
129+ if (new File (path ).exists ()) {
130+ return path ;
131+ }
132+ }
133+ }
134+ return null ;
135+ }
136+
137+ private void openDefaultSystemBrowser (URL url ){
138+ if (OSHelper .isWindows ()) { //windows
139+ openDefaultSystemBrowserInWindows (url );
140+ } else if (OSHelper .isMac ()) { // mac os
141+ openDefaultSystemBrowserInMac (url );
142+ } else if (OSHelper .isLinux ()) { //linux or unix os
143+ openDefaultSystemBrowserInLinux (url );
144+ } else {
145+ throw new UnsupportedOperationException (OSHelper .getOs () + "Operating system not supported exception." );
146+ }
147+ }
109148
110- private void openDefaultSystemBrowser (URL url ) {
149+ private static void openDefaultSystemBrowserInWindows (URL url ){
111150 try {
112151 if (Desktop .isDesktopSupported () && Desktop .getDesktop ().isSupported (Desktop .Action .BROWSE )) {
113152 Desktop .getDesktop ().browse (url .toURI ());
@@ -121,6 +160,41 @@ private void openDefaultSystemBrowser(URL url) {
121160 }
122161 }
123162
163+ private static void openDefaultSystemBrowserInMac (URL url ){
164+ Runtime runtime = Runtime .getRuntime ();
165+ try {
166+ runtime .exec ("open " + url );
167+ } catch (IOException e ) {
168+ throw new RuntimeException (e );
169+ }
170+ }
171+
172+ private static void openDefaultSystemBrowserInLinux (URL url ){
173+ String sudoUser = System .getenv ("SUDO_USER" );
174+ if (sudoUser != null && !sudoUser .isEmpty ()) {
175+ throw new MsalClientException (LINUX_XDG_OPEN , LINUX_OPEN_AS_SUDO_NOT_SUPPORTED );
176+ }
177+
178+ boolean opened = false ;
179+ List <String > openTools = getOpenToolsLinux ();
180+ for (String openTool : openTools ) {
181+ String openToolPath = getExecutablePath (openTool );
182+ if (openToolPath != null ) {
183+ Runtime runtime = Runtime .getRuntime ();
184+ try {
185+ runtime .exec (openTool + url );
186+ } catch (IOException e ) {
187+ throw new RuntimeException (e );
188+ }
189+ opened = true ;
190+ break ;
191+ }
192+ }
193+ if (!opened ) {
194+ throw new MsalClientException (LINUX_XDG_OPEN , LINUX_OPEN_AS_SUDO_NOT_SUPPORTED );
195+ }
196+ }
197+
124198 private AuthorizationResult getAuthorizationResultFromHttpListener () {
125199 AuthorizationResult result = null ;
126200 try {
0 commit comments