Skip to content

Integrated windows auth #370

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 41 commits into from
Aug 8, 2019
Merged
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
12b7240
patch-closest-facility-static-readme (#363)
JonLavi Jun 14, 2019
3d6d13b
delete sample calculate distance 3D (#365)
JonLavi Jun 18, 2019
61c2af9
Patch/ClosestFacilityStatic- Edit readme 'how to use' (#364)
JonLavi Jun 18, 2019
8a12999
patch oAuth sample custom challengehandler (#366)
JonLavi Jun 20, 2019
97a7461
working sample
JonLavi Jun 24, 2019
524f97e
comments, formatting, UI improvements
JonLavi Jun 24, 2019
cc63013
UI, screenshot, readme
JonLavi Jun 24, 2019
903c1ea
readme formatting
JonLavi Jun 24, 2019
684a10a
code formatting
JonLavi Jun 24, 2019
88b3c1f
ui improvements, screenshot
JonLavi Jun 25, 2019
111b897
comments, formatting
JonLavi Jun 25, 2019
223ca40
readme tags
JonLavi Jun 25, 2019
451c496
javadoc comments
JonLavi Jun 25, 2019
96e93c8
ui improvements
JonLavi Jun 28, 2019
8993206
ui improvements
JonLavi Jun 28, 2019
989e050
refactoring
JonLavi Jun 28, 2019
099942b
comments
JonLavi Jun 28, 2019
a48f046
address review suggestions
JonLavi Jul 3, 2019
b210e00
smaller UI
JonLavi Jul 3, 2019
48b8dc1
update screenshot
JonLavi Jul 3, 2019
4685d13
listview holds portal item ids
JonLavi Jul 3, 2019
863ea73
Update README.md, comments
JonLavi Jul 4, 2019
91e140b
update README.md
JonLavi Jul 4, 2019
d9139fa
rebase to split dev branch
JonLavi Jul 18, 2019
d287f06
fix package and path names
JonLavi Jul 18, 2019
ccb6737
delete irrelevant files
JonLavi Jul 18, 2019
9dd1f82
readme to MD
JonLavi Jul 18, 2019
3dbdd2a
add README.metadata.json
JonLavi Jul 26, 2019
e843f3f
updated README.metadata.json
JonLavi Jul 26, 2019
3ecb359
remove public search, refactoring
JonLavi Jul 26, 2019
3c44768
whitespace
JonLavi Jul 26, 2019
f29caf4
cell factory to class, fxml tidying
JonLavi Aug 6, 2019
9d96a7a
error handling, comments, refactoring
JonLavi Aug 6, 2019
bf13102
error handling
JonLavi Aug 6, 2019
0979f16
remove loading/portal info text
JonLavi Aug 6, 2019
3421276
class member to local var
JonLavi Aug 6, 2019
4b3bd3b
update Readme.md for UI changes and review suggestions
JonLavi Aug 7, 2019
7a38802
refactoring
JonLavi Aug 7, 2019
c7fec86
fix typo
JonLavi Aug 7, 2019
a5f9d43
Move construction of portal query parameters to its own line
tschie Aug 7, 2019
7e409e8
small UI improvements, update screenshot
JonLavi Aug 8, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public AuthenticationChallengeResponse handleChallenge(AuthenticationChallenge c
// get the authorization code by sending user to the authorization screen
String authorizationUrl = OAuthTokenCredentialRequest.getAuthorizationUrl(
config.getPortalUrl(), config.getClientId(), config.getRedirectUri(), 0);
String authorizationCode = OAuthChallenge.getAuthorizationCode(authorizationUrl);
String authorizationCode = OAuthChallenge.getAuthorizationCode(authorizationUrl + "&display=classic");

// use the authorization code to get a token
OAuthTokenCredentialRequest request = new OAuthTokenCredentialRequest(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,8 @@ chosen folder.</p>
<li>PortalItem</li>
<li>PortalUserContent</li>
</ul>


<h2>Additional information</h2>

<p>The JavaFX <code>WebEngine</code> used in the <code>OAuthChallengeHandler</code> in this sample may not support rendering of some modern web elements returned by the <code>AuthorizationURL</code>. For this reason, we append <code>&display=classic</code> to the authorization URL, to ensure it renders properly.</p>
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ public void start(Stage stage) throws Exception {
// display the route on the graphics overlay
graphicsOverlay.getGraphics().add(new Graphic(closestFacilityRoute.getRouteGeometry(), simpleLineSymbol));

// hide the progress indicator and enable the reset button
// hide the progress indicator
progressIndicator.setVisible(false);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

<h2>How to use the sample</h2>

<p>Click the 'Solve Routes' button to determine and display the route from each incident (fire) to the nearest facility (fire station). Click the reset button to remove the views.</p>
<p>Click the 'Solve Routes' button to determine and display the route from each incident (fire) to the nearest facility (fire station).</p>

<h2>How it works</h2>

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
* Copyright 2019 Esri.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/

package com.esri.samples.portal.integrated_windows_authentication;

import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.control.Alert;
import javafx.scene.control.ButtonType;
import javafx.scene.control.Dialog;
import javafx.scene.control.PasswordField;
import javafx.scene.control.TextField;

import com.esri.arcgisruntime.security.UserCredential;

class AuthenticationDialog extends Dialog {

@FXML private TextField userdomain;
@FXML private PasswordField password;
@FXML private ButtonType cancelButton;
@FXML private ButtonType continueButton;

AuthenticationDialog() {

FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/iwa_auth_dialog.fxml"));
loader.setRoot(this);
loader.setController(this);

setTitle("Authenticate");

try {
loader.load();
} catch (Exception e) {
e.printStackTrace();
}

setResultConverter(dialogButton -> {
if (dialogButton == continueButton) {
if (!userdomain.getText().equals("") && !password.getText().equals("")) {
try {
return new UserCredential(userdomain.getText(), password.getText());
} catch (Exception e) {
new Alert(Alert.AlertType.ERROR, e.getMessage()).show();
}
} else {
new Alert(Alert.AlertType.ERROR, "Missing credentials").show();
}
}
return null;
});
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/*
* Copyright 2019 Esri.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/

package com.esri.samples.portal.integrated_windows_authentication;

import java.util.concurrent.CountDownLatch;

import javafx.application.Platform;
import javafx.scene.control.Alert;

import com.esri.arcgisruntime.loadable.LoadStatus;
import com.esri.arcgisruntime.portal.Portal;
import com.esri.arcgisruntime.security.AuthenticationChallenge;
import com.esri.arcgisruntime.security.AuthenticationChallengeHandler;
import com.esri.arcgisruntime.security.AuthenticationChallengeResponse;
import com.esri.arcgisruntime.security.UserCredential;

/**
* Handler to be used when accessing a secured resource.
*/
final class IWAChallengeHandler implements AuthenticationChallengeHandler {

private UserCredential userCredential;

/**
* Handles challenge before accessing a secured resource.
*
* @param authenticationChallenge the authentication challenge to handle
* @return the AuthenticationChallengeResponse indicating which action to take
*/
@Override
public AuthenticationChallengeResponse handleChallenge(AuthenticationChallenge authenticationChallenge) {

if (authenticationChallenge.getType() == AuthenticationChallenge.Type.USER_CREDENTIAL_CHALLENGE && authenticationChallenge.getRemoteResource() instanceof Portal) {

// If challenge has been requested by a Portal and the Portal has been loaded, cancel the challenge
// This is required as some layers have private portal items associated with them and we don't
// want to auth against them
if (((Portal) authenticationChallenge.getRemoteResource()).getLoadStatus() == LoadStatus.LOADED) {
return new AuthenticationChallengeResponse(AuthenticationChallengeResponse.Action.CANCEL, authenticationChallenge);
}

int maxAttempts = 5;
if (authenticationChallenge.getFailureCount() > maxAttempts) {
// exceeded maximum amount of attempts. Act like it was a cancel
new Alert(Alert.AlertType.ERROR, "Exceeded maximum amount of attempts. Please try again!").show();
return new AuthenticationChallengeResponse(AuthenticationChallengeResponse.Action.CANCEL, authenticationChallenge);
}

// create a countdown latch with a count of one to synchronize the authentication dialog
CountDownLatch authenticationCountDownLatch = new CountDownLatch(1);
// show the authentication dialog and capture the user credentials
Platform.runLater(() -> {
AuthenticationDialog authenticationDialog = new AuthenticationDialog();
authenticationDialog.show();
authenticationDialog.setOnCloseRequest(r -> {
userCredential = (UserCredential) authenticationDialog.getResult();
authenticationCountDownLatch.countDown();
});
});

try {
authenticationCountDownLatch.await();
} catch (InterruptedException e) {
new Alert(Alert.AlertType.ERROR, "Interruption handling AuthenticationChallengeResponse: " + e.getMessage()).show();
}

// if credentials were set, return a new auth challenge response with them. otherwise, act like it was a cancel action
if (userCredential != null) {
return new AuthenticationChallengeResponse(AuthenticationChallengeResponse.Action.CONTINUE_WITH_CREDENTIAL, userCredential);
}
}

// no credentials were set, return a new auth challenge response with with a cancel action
return new AuthenticationChallengeResponse(AuthenticationChallengeResponse.Action.CANCEL, authenticationChallenge);
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading