...
Code Block |
---|
/**
*
* Login using BankID SE
*
* All texts, flows and documentation is available at
*
* https://www.bankid.com/assets/bankid/rp/bankid-relying-party-guidelines-v2.15.pdf
*
* @author Kim Rasmussen
* @version $Revision$
*
* <pre>
* Ceptor - http://ceptor.io
* Copyright(c) 2017, Asseco Denmark A/S, All rights reserved.
*
* This source code is confidential.
* </pre>
*/
public class SwedishBankIDAuth extends VerticalLayout {
private static final long serialVersionUID = 1L;
private IController controller;
private TextField personNummer;
private Button next;
private Button thisComputer;
private Button mobileDevice;
private Refresher refresher;
private boolean isIdProvided = false;
private boolean isMobileDevice = DeviceUtils.isMobileDevice();
public SwedishBankIDAuth(IController controller) {
this.controller = controller;
setStyleName("small-padding");
setWidth("100%");
setMargin(false);
populateInitialGUI();
}
private void populateInitialGUI() {
removeAllComponents();
// Differ messages depending on running in browser or on mobile
String promptKey = isMobileDevice ? "RFA20" : "RFA19";
addComponent(new Label(Language.getText(promptKey, promptKey)));
thisComputer = new Button(Language.getText(promptKey+"_THIS", promptKey+"_THIS"), e -> useThisComputer());
thisComputer.setStyleName("custom");
mobileDevice = new Button(Language.getText(promptKey+"_MOBILE", promptKey+"_MOBILE"), e -> useMobileDevice());
thisComputer.setStyleName("custom");
HorizontalLayout hl = new HorizontalLayout();
hl.addComponents(thisComputer, mobileDevice);
addComponent(hl);
// Start with clean slate
try {
Agent.getInstance().setStateVariable(JSPHelper.getSessionID(), "bankidse_orderRef", null, false);
Agent.getInstance().setStateVariable(JSPHelper.getSessionID(), "bankidse_autoStartToken", null, false);
} catch(PTException e) {
// OK to ignore
}
}
private void useThisComputer() {
isIdProvided = false;
// No ID needed, since we are using the same device
try {
// Credentials here ensure that only BankID mobile can be used.
Agent.getInstance().logon(JSPHelper.getSessionID(), AuthTypes.AUTHTYPE_BANKID_SE, "", "{\"certificatePolicies\": [\"1.2.752.78.1.5\"]}"); // TODO: Need to consider test environment vs production
} catch(PTException e) {
if (e.getErrorCode() != AuthErrorCodes.ERROR_NOT_YET_COMPLETED) { // Error 19 means that authentication is started
handleError(e);
return;
}
}
redirectNow();
}
private void redirectNow() {
// If we get here, we can redirect
try {
String autoStartToken = Agent.getInstance().getStateVariable(JSPHelper.getSessionID(), "bankidse_autoStartToken");
String challenge = Base64.encode(UUID.randomUUID().toString());
Agent.getInstance().setStateVariable(JSPHelper.getSessionID(), "challenge", challenge, false);
// Redirect to BankID on the same computer/device
String url = "bankid:///?autostarttoken="+URLUtils.encodeURL(autoStartToken)+"&rpref="+URLUtils.encodeURL(challenge)+"&redirect="+URLUtils.encodeURL(Page.getCurrent().getLocation().toString());
// When we get back, we need to poll immediately to see if it worked.
initiatePoll();
Page.getCurrent().setLocation(url);
} catch (PTException e) {
handleError(e);
}
}
private void handleError(PTException e) {
removeAllComponents();
if (refresher != null) {
removeExtension(refresher);
refresher = null;
}
Label l = new Label(getMessage(e));
l.addStyleName(ValoTheme.LABEL_FAILURE);
addComponent(l);
addComponent(new Button(Language.getText("bankid.retry", "Try again"), (source) -> populateInitialGUI()));
}
private void initiatePoll() {
// Start the polling...
refresher = new Refresher();
refresher.setRefreshInterval(2000);
addExtension(refresher);
refresher.addListener(source -> pollStatus());
}
private void pollStatus() {
try {
// Credentials here ensure that only BankID mobile can be used.
Agent.getInstance().logon(JSPHelper.getSessionID(), AuthTypes.AUTHTYPE_BANKID_SE, "", "");
if (refresher != null) {
removeExtension(refresher);
refresher = null;
}
// It worked, login is done.
controller.bankIDLoginCompleted();
return;
} catch(PTException e) {
if (e.getErrorCode() != AuthErrorCodes.ERROR_NOT_YET_COMPLETED) { // Error 19 means that authentication is started
handleError(e);
return;
}
removeAllComponents();
addComponent(new Label(getMessage(e)));
}
}
private String getMessage(PTException e) {
String progressStatus = e.getErrorText();
if (progressStatus == null)
return e.toString();
String message = progressStatus;
switch(progressStatus) {
case "OUTSTANDING_TRANSACTION":
case "NO_CLIENT":
message = Language.getText("RFA1", "RFA1");
break;
case "ALREADY_IN_PROGRESS":
case "CANCELLED":
message = Language.getText("RFA3", "RFA3");
break;
case "RETRY":
case "INTERNAL_ERROR":
message = Language.getText("RFA5", "RFA5");
break;
case "USER_CANCEL":
message = Language.getText("RFA6", "RFA6");
break;
case "EXPIRED_TRANSACTION":
message = Language.getText("RFA8", "RFA8");
break;
case "USER_SIGN":
message = Language.getText("RFA9", "RFA9");
break;
case "CLIENT_ERR":
message = Language.getText("RFA12", "RFA12");
break;
case "STARTED":
if (isMobileDevice) {
if (isIdProvided)
message = Language.getText("RFA14_B", "RFA14_B");
else
message = Language.getText("RFA15_B", "RFA15_B");
} else { // PC is used
if (isIdProvided)
message = Language.getText("RFA14_A", "RFA14_A");
else
message = Language.getText("RFA15_A", "RFA15_A");
}
break;
case "START_FAILED":
message = Language.getText("RFA17", "RFA17");
break;
}
return message;
}
/**
* Use mobile (or other device if already running on mobile)
*/
private void useMobileDevice() {
// Prompt for ID
setupPersonnummer();
}
private void setupPersonnummer() {
removeAllComponents();
personNummer = new TextField();
personNummer.setPlaceholder("ID");
personNummer.setIcon(VaadinIcons.USER);
personNummer.setStyleName(ValoTheme.TEXTFIELD_INLINE_ICON);
personNummer.setWidth("100%");
addComponent(personNummer);
next = new Button(Language.getText("RFA18", "RFA18"), e -> nextBtnClickListener());
next.setStyleName("custom");
addComponent(next);
setComponentAlignment(next, Alignment.BOTTOM_RIGHT);
}
private void nextBtnClickListener() {
if (personNummer.isEmpty()) {
Notification.show(Language.getText("bankid.emptyid", "Please enter ID"));
personNummer.focus();
return;
}
isIdProvided = true;
try {
Agent.getInstance().logon(JSPHelper.getSessionID(), AuthTypes.AUTHTYPE_BANKID_SE, personNummer.getValue().trim(), "");
controller.bankIDLoginCompleted();
} catch(PTException e) {
if (e.getErrorCode() != AuthErrorCodes.ERROR_NOT_YET_COMPLETED) { // Error 19 means that authentication is started
handleError(e);
return;
}
}
removeAllComponents();
addComponent(new Label(Language.getText("RFA1", "RFA1")));
initiatePoll();
}
} |
...