Package com.codeborne.security.mobileid

Source Code of com.codeborne.security.mobileid.MobileIDAuthenticator

package com.codeborne.security.mobileid;

import com.codeborne.security.AuthenticationException;
import com.codeborne.security.digidoc.DigiDocServicePortType;
import com.codeborne.security.digidoc.DigiDocService_Service;
import com.codeborne.security.digidoc.DigiDocService_ServiceLocator;

import javax.xml.rpc.ServiceException;
import javax.xml.rpc.holders.IntHolder;
import javax.xml.rpc.holders.StringHolder;
import java.net.MalformedURLException;
import java.net.URL;
import java.rmi.RemoteException;

import static com.codeborne.security.AuthenticationException.Code.*;

/**
* Authenticates with Mobile-ID.<br>
* Can be used as a preconfigured singleton (eg Spring bean).<br>
* <p>Use {@link #startLogin} to initiate the login session and display challenge to the user,
* then {@link #waitForLogin(MobileIDSession)} to wait for the authentication to complete.</p>
* <p>Various setters can be used to configure the behaviour.</p>
*/
public class MobileIDAuthenticator {
  private String language = "EST";
  private String serviceName = "Testimine";
  private String loginMessage = "";
  private int retryCount = 60;
  private int pollIntervalMs = 3000;
  private final String messagingMode = "asynchClientServer";

  DigiDocServicePortType digiDocServicePortType;

  public MobileIDAuthenticator() {
  }

  public MobileIDAuthenticator(String digidocServiceURL) throws MalformedURLException {
    setDigidocServiceURL(new URL(digidocServiceURL));
  }

  public MobileIDAuthenticator(String digidocServiceURL, String serviceName) throws MalformedURLException {
    setDigidocServiceURL(new URL(digidocServiceURL));
    this.serviceName = serviceName;
  }

  public MobileIDAuthenticator(URL digidocServiceURL) {
    setDigidocServiceURL(digidocServiceURL);
  }

  public MobileIDAuthenticator(URL digidocServiceURL, String serviceName) {
    setDigidocServiceURL(digidocServiceURL);
    this.serviceName = serviceName;
  }

  public final MobileIDAuthenticator setDigidocServiceURL(URL digidocServiceURL) {
    DigiDocService_Service digiDocService = new DigiDocService_ServiceLocator();
    try {
      digiDocServicePortType = digiDocService.getDigiDocService(digidocServiceURL);
    } catch (ServiceException e) {
      throw new RuntimeException("Failed to initialize Mobile-ID support", e);
    }
    return this;
  }

  public void setLanguage(String language) {
    this.language = language;
  }

  public void setServiceName(String serviceName) {
    this.serviceName = serviceName;
  }

  public void setLoginMessage(String loginMessage) {
    this.loginMessage = loginMessage;
  }

  public void setRetryCount(int retryCount) {
    this.retryCount = retryCount;
  }

  public void setPollIntervalMs(int pollIntervalMs) {
    this.pollIntervalMs = pollIntervalMs;
  }

  /**
   * Initiates the login session. Note: returned session already contains user's info, but the authenticity is not yet verified.
   * @param personalCode user's personal code
   * @param countryCode two letter country code, eg EE
   * @throws AuthenticationException is authentication unsuccessful
   */
  public MobileIDSession startLogin(String personalCode, String countryCode) throws AuthenticationException {
    return startLogin(personalCode, countryCode, null);
  }

  /**
   * Initiates the login session. Note: returned session already contains user's info, but the authenticity is not yet verified.
   * @param phone phone number, either a local one (work for EE) or with country code (eg +37255667788).
   * @throws AuthenticationException is authentication unsuccessful
   */
  public MobileIDSession startLogin(String phone) throws AuthenticationException {
    return startLogin(null, null, phone);
  }
 
  protected MobileIDSession startLogin(String personalCode, String countryCode, String phone) throws AuthenticationException {
    if (digiDocServicePortType == null) {
      throw new IllegalStateException("digidocServiceURL is not initialized");
    }

    if (phone.startsWith("+")) phone = phone.substring(1);
    if (!phone.startsWith("372")) phone = "372" + phone;

    IntHolder sessCode = new IntHolder();
    StringHolder result = new StringHolder();
    StringHolder firstName = new StringHolder();
    StringHolder lastName = new StringHolder();
    StringHolder personalCodeHolder = new StringHolder();
    StringHolder challenge = new StringHolder();

    try {
      digiDocServicePortType.mobileAuthenticate(personalCode, countryCode, phone, language, serviceName, loginMessage, generateSPChallenge(),
          messagingMode, 0, false, false, sessCode, result,
          personalCodeHolder, firstName, lastName, new StringHolder(), new StringHolder(), new StringHolder(), challenge,
          new StringHolder(), new StringHolder());
    }
    catch (RemoteException e) {
      throw new AuthenticationException(e);
    }

    if (!"OK".equals(result.value))
      throw new AuthenticationException(valueOf(result.value));

    return new MobileIDSession(sessCode.value, challenge.value, firstName.value, lastName.value, personalCodeHolder.value);
  }

  protected String generateSPChallenge() {
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < 20; i++) sb.append((int)(Math.random() * 10));
    return sb.toString();
  }

  /**
   * Waits until user confirms their identity using the mobile device.
   * @param session previously returned by {@link #startLogin}
   * @throws AuthenticationException is authentication unsuccessful
   */
  public MobileIDSession waitForLogin(MobileIDSession session) throws AuthenticationException {
    StringHolder status = new StringHolder("OUTSTANDING_TRANSACTION");
    int tryCount = 0;
    while (sleep(pollIntervalMs) && "OUTSTANDING_TRANSACTION".equals(status.value) && tryCount < retryCount) {
      try {
        digiDocServicePortType.getMobileAuthenticateStatus(session.sessCode, false, status, new StringHolder());
      }
      catch (RemoteException e) {
        throw new AuthenticationException(e);
      }
      tryCount++;
    }

    if (!"USER_AUTHENTICATED".equals(status.value))
      throw new AuthenticationException(valueOf(status.value));

    return session;
  }

  private boolean sleep(int sleepTimeMilliseconds) {
    try {
      Thread.sleep(sleepTimeMilliseconds);
      return true;
    }
    catch (InterruptedException e) {
      return false;
    }
  }
}
TOP

Related Classes of com.codeborne.security.mobileid.MobileIDAuthenticator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.