Skip to content

Commit

Permalink
Add support for Samsung Internet Browser and Opera on Android (#254)
Browse files Browse the repository at this point in the history
Add device info to logging
  • Loading branch information
PeterOrneholm authored May 18, 2020
1 parent f090be8 commit 2fea270
Show file tree
Hide file tree
Showing 21 changed files with 228 additions and 105 deletions.
16 changes: 11 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -384,11 +384,17 @@ A more technical deep dive of the cookies can be found in [this issue](https://g

We aim at supporting the latest version of all major browsers (Edge, Chrome, Firefox, Safari) both on desktop and on mobile.

All browsers on mobile are supported, but the full automated flow on same device (redirect between apps) are supported on these:
- Safari on iOS
- Chrome on iOS
- Firefox on iOS
- All browsers on Android
All browsers on mobile are supported, but the redirect flow are tested on these:
- iOS
- Safari
- Chrome
- Firefox
- Android
- Chrome
- Firefox
- Samsung Internet Browser
- Opera
- Edge

If you aim to support IE11 a polyfill for some JavaScript features we are using is needed.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<PackageId>ActiveLogin.Authentication.BankId.Api</PackageId>

<VersionPrefix>4.0.0</VersionPrefix>
<VersionSuffix>beta-1</VersionSuffix>
<VersionSuffix>beta-2</VersionSuffix>
<AssemblyVersion>4.0.0.0</AssemblyVersion>
<FileVersion Condition="'$(BUILD_BUILDNUMBER)' == ''">$(VersionPrefix).0</FileVersion>
<FileVersion Condition="'$(BUILD_BUILDNUMBER)' != ''">$(VersionPrefix).$(BUILD_BUILDNUMBER)</FileVersion>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<PackageId>ActiveLogin.Authentication.BankId.AspNetCore.Azure</PackageId>

<VersionPrefix>4.0.0</VersionPrefix>
<VersionSuffix>beta-1</VersionSuffix>
<VersionSuffix>beta-2</VersionSuffix>
<AssemblyVersion>4.0.0.0</AssemblyVersion>
<FileVersion Condition="'$(BUILD_BUILDNUMBER)' == ''">$(VersionPrefix).0</FileVersion>
<FileVersion Condition="'$(BUILD_BUILDNUMBER)' != ''">$(VersionPrefix).$(BUILD_BUILDNUMBER)</FileVersion>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<PackageId>ActiveLogin.Authentication.BankId.AspNetCore.AzureMonitor</PackageId>

<VersionPrefix>4.0.0</VersionPrefix>
<VersionSuffix>beta-1</VersionSuffix>
<VersionSuffix>beta-2</VersionSuffix>
<AssemblyVersion>4.0.0.0</AssemblyVersion>
<FileVersion Condition="'$(BUILD_BUILDNUMBER)' == ''">$(VersionPrefix).0</FileVersion>
<FileVersion Condition="'$(BUILD_BUILDNUMBER)' != ''">$(VersionPrefix).$(BUILD_BUILDNUMBER)</FileVersion>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using ActiveLogin.Authentication.BankId.Api;
using ActiveLogin.Authentication.BankId.AspNetCore.Events;
using ActiveLogin.Authentication.BankId.AspNetCore.Events.Infrastructure;
using ActiveLogin.Authentication.BankId.AspNetCore.SupportedDevice;
using ActiveLogin.Identity.Swedish;
using ActiveLogin.Identity.Swedish.Extensions;
using Microsoft.ApplicationInsights;
Expand Down Expand Up @@ -33,10 +34,15 @@ public class BankIdApplicationInsightsEventListener : BankIdTypedEventListener
private const string PropertyName_BankIdOrderRef = "AL_BankId_OrderRef";
private const string PropertyName_BankIdCollectHintCode = "AL_BankId_CollectHintCode";

private const string PropertyName_UserDeviceIpAddress = "AL_BankId_User_DeviceIpAddress";
private const string PropertyName_UserCertNotBefore = "AL_User_CertNotBefore";
private const string PropertyName_UserCertNotAfter = "AL_User_CertNotAfter";

private const string PropertyName_UserDeviceIpAddress = "AL_BankId_User_Device_IpAddress";
private const string PropertyName_UserDeviceBrowser = "AL_BankId_User_Device_Browser";
private const string PropertyName_UserDeviceOs = "AL_BankId_User_Device_Os";
private const string PropertyName_UserDeviceType = "AL_BankId_User_Device_Type";
private const string PropertyName_UserDeviceOsVersion = "AL_BankId_User_Device_OsVersion";

private const string PropertyName_UserName = "AL_User_Name";
private const string PropertyName_UserGivenName = "AL_User_GivenName";
private const string PropertyName_UserSurname = "AL_User_Surname";
Expand Down Expand Up @@ -98,20 +104,27 @@ private static string GetBooleanProperty(bool property)

public override Task HandleAuthSuccessEvent(BankIdAuthSuccessEvent e)
{
var properties = new Dictionary<string, string>
{
{ PropertyName_BankIdOrderRef, e.OrderRef }
};
AddUserDeviceProperties(properties, e.DetectedUserDevice);

return Track(
e,
new Dictionary<string, string>
{
{ PropertyName_BankIdOrderRef, e.OrderRef }
},
properties,
personalIdentityNumber: e.PersonalIdentityNumber
);
}

public override Task HandleAuthFailureEvent(BankIdAuthErrorEvent e)
{
var properties = new Dictionary<string, string>();
AddUserDeviceProperties(properties, e.DetectedUserDevice);

return Track(
e,
properties,
personalIdentityNumber: e.PersonalIdentityNumber,
exception: e.BankIdApiException
);
Expand Down Expand Up @@ -269,5 +282,13 @@ private void AddPersonalIdentityNumberProperties(Dictionary<string, string> prop
}
}
}

private void AddUserDeviceProperties(Dictionary<string, string> properties, BankIdSupportedDevice userDevice)
{
properties.Add(PropertyName_UserDeviceBrowser, userDevice.DeviceBrowser.ToString());
properties.Add(PropertyName_UserDeviceOs, userDevice.DeviceOs.ToString());
properties.Add(PropertyName_UserDeviceType, userDevice.DeviceType.ToString());
properties.Add(PropertyName_UserDeviceOsVersion, userDevice.DeviceOsVersion.ToString());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
<RootNamespace>ActiveLogin.Authentication.BankId.AspNetCore.QrCoder</RootNamespace>

<VersionPrefix>4.0.0</VersionPrefix>
<VersionSuffix>beta-1</VersionSuffix>
<VersionSuffix>beta-2</VersionSuffix>
<AssemblyVersion>4.0.0.0</AssemblyVersion>
<FileVersion Condition="'$(BUILD_BUILDNUMBER)' == ''">$(VersionPrefix).0</FileVersion>
<FileVersion Condition="'$(BUILD_BUILDNUMBER)' != ''">$(VersionPrefix).$(BUILD_BUILDNUMBER)</FileVersion>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
<PackageId>ActiveLogin.Authentication.BankId.AspNetCore</PackageId>

<VersionPrefix>4.0.0</VersionPrefix>
<VersionSuffix>beta-1</VersionSuffix>
<VersionSuffix>beta-2</VersionSuffix>
<AssemblyVersion>4.0.0.0</AssemblyVersion>
<FileVersion Condition="'$(BUILD_BUILDNUMBER)' == ''">$(VersionPrefix).0</FileVersion>
<FileVersion Condition="'$(BUILD_BUILDNUMBER)' != ''">$(VersionPrefix).$(BUILD_BUILDNUMBER)</FileVersion>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ namespace ActiveLogin.Authentication.BankId.AspNetCore.Areas.BankIdAuthenticatio
[AllowAnonymous]
public class BankIdApiController : Controller
{
private const string UserAgentHttpHeaderName = "User-Agent";

private readonly UrlEncoder _urlEncoder;
private readonly IBankIdUserMessage _bankIdUserMessage;
private readonly IBankIdUserMessageLocalizer _bankIdUserMessageLocalizer;
Expand Down Expand Up @@ -105,6 +107,7 @@ public async Task<ActionResult<BankIdLoginApiInitializeResponse>> Initialize(Ban
}
}

var detectedUserDevice = GetDetectedUserDevice();
AuthResponse authResponse;
try
{
Expand All @@ -113,7 +116,7 @@ public async Task<ActionResult<BankIdLoginApiInitializeResponse>> Initialize(Ban
}
catch (BankIdApiException bankIdApiException)
{
await _bankIdEventTrigger.TriggerAsync(new BankIdAuthErrorEvent(personalIdentityNumber, bankIdApiException));
await _bankIdEventTrigger.TriggerAsync(new BankIdAuthErrorEvent(personalIdentityNumber, bankIdApiException, detectedUserDevice));

var errorStatusMessage = GetStatusMessage(bankIdApiException);
return BadRequestJsonResult(new BankIdLoginApiErrorResponse(errorStatusMessage));
Expand All @@ -122,24 +125,20 @@ public async Task<ActionResult<BankIdLoginApiInitializeResponse>> Initialize(Ban
var orderRef = authResponse.OrderRef;
var protectedOrderRef = _orderRefProtector.Protect(new BankIdOrderRef(orderRef));

await _bankIdEventTrigger.TriggerAsync(new BankIdAuthSuccessEvent(personalIdentityNumber, orderRef));
await _bankIdEventTrigger.TriggerAsync(new BankIdAuthSuccessEvent(personalIdentityNumber, orderRef, detectedUserDevice));

if (unprotectedLoginOptions.AutoLaunch)
{
var detectedDevice = _bankIdSupportedDeviceDetector.Detect(HttpContext.Request.Headers["User-Agent"]);
var bankIdRedirectUri = GetBankIdRedirectUri(request, authResponse, detectedDevice);

var deviceWillReloadPageOnReturn = _bankIdLauncher.GetDeviceWillReloadPageOnReturnFromBankIdApp(detectedDevice);
var deviceMightRequireUserInteraction = _bankIdLauncher.GetDeviceMightRequireUserInteractionToLaunchBankIdApp(detectedDevice);

var launchInfo = GetBankIdLaunchInfo(request, authResponse);

// Don't check for status if the browser will reload on return
if (deviceWillReloadPageOnReturn)
if (launchInfo.DeviceWillReloadPageOnReturnFromBankIdApp)
{
return OkJsonResult(BankIdLoginApiInitializeResponse.AutoLaunch(protectedOrderRef, bankIdRedirectUri, deviceMightRequireUserInteraction));
return OkJsonResult(BankIdLoginApiInitializeResponse.AutoLaunch(protectedOrderRef, launchInfo.LaunchUrl, launchInfo.DeviceMightRequireUserInteractionToLaunchBankIdApp));
}
else
{
return OkJsonResult(BankIdLoginApiInitializeResponse.AutoLaunchAndCheckStatus(protectedOrderRef, bankIdRedirectUri, deviceMightRequireUserInteraction));
return OkJsonResult(BankIdLoginApiInitializeResponse.AutoLaunchAndCheckStatus(protectedOrderRef, launchInfo.LaunchUrl, launchInfo.DeviceMightRequireUserInteractionToLaunchBankIdApp));
}
}

Expand All @@ -151,7 +150,7 @@ public async Task<ActionResult<BankIdLoginApiInitializeResponse>> Initialize(Ban

return OkJsonResult(BankIdLoginApiInitializeResponse.ManualLaunch(protectedOrderRef));
}

private AuthRequest GetAuthRequest(SwedishPersonalIdentityNumber? personalIdentityNumber, BankIdLoginOptions loginOptions)
{
var endUserIp = _endUserIpResolver.GetEndUserIp(HttpContext);
Expand All @@ -169,17 +168,15 @@ private AuthRequest GetAuthRequest(SwedishPersonalIdentityNumber? personalIdenti
return new AuthRequest(endUserIp, personalIdentityNumberString, authRequestRequirement);
}

private string GetBankIdRedirectUri(BankIdLoginApiInitializeRequest request, AuthResponse authResponse, BankIdSupportedDevice detectedDevice)
private BankIdLaunchInfo GetBankIdLaunchInfo(BankIdLoginApiInitializeRequest request, AuthResponse authResponse)
{
var returnRedirectUri = GetAbsoluteUrl(Url.Action("Login", "BankId", new
{
returnUrl = request.ReturnUrl,
loginOptions = request.LoginOptions
}));
var launchUrlRequest = new LaunchUrlRequest(returnRedirectUri, authResponse.AutoStartToken);
var bankIdRedirectUri = _bankIdLauncher.GetLaunchUrl(detectedDevice, launchUrlRequest);

return bankIdRedirectUri;
return _bankIdLauncher.GetLaunchInfo(launchUrlRequest, HttpContext);
}

private string GetAbsoluteUrl(string returnUrl)
Expand Down Expand Up @@ -222,7 +219,7 @@ public async Task<ActionResult> Status(BankIdLoginApiStatusRequest request)
return BadRequestJsonResult(new BankIdLoginApiErrorResponse(errorStatusMessage));
}

var statusMessage = GetStatusMessage(collectResponse, unprotectedLoginOptions, HttpContext.Request);
var statusMessage = GetStatusMessage(collectResponse, unprotectedLoginOptions);

if (collectResponse.GetCollectStatus() == CollectStatus.Pending)
{
Expand Down Expand Up @@ -279,10 +276,10 @@ private ActionResult CollectPending(CollectResponse collectResponse, string stat
return OkJsonResult(BankIdLoginApiStatusResponse.Pending(statusMessage));
}

private string GetStatusMessage(CollectResponse collectResponse, BankIdLoginOptions unprotectedLoginOptions, HttpRequest request)
private string GetStatusMessage(CollectResponse collectResponse, BankIdLoginOptions unprotectedLoginOptions)
{
var authPersonalIdentityNumberProvided = PersonalIdentityNumberProvided(unprotectedLoginOptions);
var detectedDevice = _bankIdSupportedDeviceDetector.Detect(request.Headers["User-Agent"]);
var detectedDevice = GetDetectedUserDevice();
var accessedFromMobileDevice = detectedDevice.DeviceType == BankIdSupportedDeviceType.Mobile;
var usingQrCode = unprotectedLoginOptions.UseQrCode;

Expand All @@ -297,6 +294,11 @@ private string GetStatusMessage(CollectResponse collectResponse, BankIdLoginOpti
return statusMessage;
}

private BankIdSupportedDevice GetDetectedUserDevice()
{
return _bankIdSupportedDeviceDetector.Detect(HttpContext.Request.Headers[UserAgentHttpHeaderName]);
}

private static bool PersonalIdentityNumberProvided(BankIdLoginOptions unprotectedLoginOptions)
{
return unprotectedLoginOptions.AllowChangingPersonalIdentityNumber
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using ActiveLogin.Authentication.BankId.Api;
using ActiveLogin.Authentication.BankId.AspNetCore.Events.Infrastructure;
using ActiveLogin.Authentication.BankId.AspNetCore.SupportedDevice;
using ActiveLogin.Identity.Swedish;

namespace ActiveLogin.Authentication.BankId.AspNetCore.Events
Expand All @@ -9,15 +10,18 @@ namespace ActiveLogin.Authentication.BankId.AspNetCore.Events
/// </summary>
public class BankIdAuthErrorEvent : BankIdEvent
{
internal BankIdAuthErrorEvent(SwedishPersonalIdentityNumber? personalIdentityNumber, BankIdApiException bankIdApiException)
internal BankIdAuthErrorEvent(SwedishPersonalIdentityNumber? personalIdentityNumber, BankIdApiException bankIdApiException, BankIdSupportedDevice detectedUserDevice)
: base(BankIdEventTypes.AuthErrorEventId, BankIdEventTypes.AuthErrorEventName, BankIdEventSeverity.Error)
{
PersonalIdentityNumber = personalIdentityNumber;
BankIdApiException = bankIdApiException;
DetectedUserDevice = detectedUserDevice;
}

public SwedishPersonalIdentityNumber? PersonalIdentityNumber { get; }

public BankIdApiException BankIdApiException { get; }

public BankIdSupportedDevice DetectedUserDevice { get; }
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using ActiveLogin.Authentication.BankId.AspNetCore.Events.Infrastructure;
using ActiveLogin.Authentication.BankId.AspNetCore.SupportedDevice;
using ActiveLogin.Identity.Swedish;

namespace ActiveLogin.Authentication.BankId.AspNetCore.Events
Expand All @@ -8,16 +9,19 @@ namespace ActiveLogin.Authentication.BankId.AspNetCore.Events
/// </summary>
public class BankIdAuthSuccessEvent : BankIdEvent
{
internal BankIdAuthSuccessEvent(SwedishPersonalIdentityNumber? personalIdentityNumber, string orderRef)
internal BankIdAuthSuccessEvent(SwedishPersonalIdentityNumber? personalIdentityNumber, string orderRef, BankIdSupportedDevice detectedUserDevice)
: base(BankIdEventTypes.AuthSuccessId, BankIdEventTypes.AuthSuccessName, BankIdEventSeverity.Success)
{
PersonalIdentityNumber = personalIdentityNumber;
OrderRef = orderRef;
DetectedUserDevice = detectedUserDevice;
}

public SwedishPersonalIdentityNumber? PersonalIdentityNumber { get; }

public string OrderRef { get; }

public BankIdSupportedDevice DetectedUserDevice { get; }
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,14 @@ namespace ActiveLogin.Authentication.BankId.AspNetCore.Events.Infrastructure
{
internal class BankIdEventTrigger : IBankIdEventTrigger
{
private readonly BankIdActiveLoginContext _bankIdActiveLoginContext;
private readonly List<IBankIdEventListener> _listeners;
private readonly BankIdActiveLoginContext _bankIdActiveLoginContext;


public BankIdEventTrigger(IEnumerable<IBankIdEventListener> listeners, IOptions<BankIdActiveLoginContext> bankIdActiveLoginContext)
{
_bankIdActiveLoginContext = bankIdActiveLoginContext.Value;
_listeners = listeners.ToList();
_bankIdActiveLoginContext = bankIdActiveLoginContext.Value;
}

public async Task TriggerAsync(BankIdEvent bankIdEvent)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,27 +1,13 @@
using ActiveLogin.Authentication.BankId.AspNetCore.SupportedDevice;
using Microsoft.AspNetCore.Http;

namespace ActiveLogin.Authentication.BankId.AspNetCore.Launcher
{
internal class BankIdDevelopmentLauncher : IBankIdLauncher
{
public string GetLaunchUrl(BankIdSupportedDevice device, LaunchUrlRequest request)
public BankIdLaunchInfo GetLaunchInfo(LaunchUrlRequest request, HttpContext httpContext)
{
if (device.DeviceOs == BankIdSupportedDeviceOs.Ios)
{
return request.RedirectUrl;
}

return "#";
}

public bool GetDeviceMightRequireUserInteractionToLaunchBankIdApp(BankIdSupportedDevice detectedDevice)
{
return false;
}

public bool GetDeviceWillReloadPageOnReturnFromBankIdApp(BankIdSupportedDevice detectedDevice)
{
return false;
// Always redirect back without user interaction in simulated mode
return new BankIdLaunchInfo(request.RedirectUrl, false, false);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
namespace ActiveLogin.Authentication.BankId.AspNetCore.Launcher
{
public class BankIdLaunchInfo
{
public BankIdLaunchInfo(string launchUrl, bool deviceMightRequireUserInteractionToLaunchBankIdApp, bool deviceWillReloadPageOnReturnFromBankIdApp)
{
LaunchUrl = launchUrl;
DeviceMightRequireUserInteractionToLaunchBankIdApp = deviceMightRequireUserInteractionToLaunchBankIdApp;
DeviceWillReloadPageOnReturnFromBankIdApp = deviceWillReloadPageOnReturnFromBankIdApp;
}

/// <summary>
/// Returns the url used to launch the BankID app.
/// </summary>
public string LaunchUrl { get; }

/// <summary>
/// If the device/browser might require user interaction, such as button click, to launch a third party app.
/// </summary>
/// <returns></returns>
public bool DeviceMightRequireUserInteractionToLaunchBankIdApp { get; }

/// <summary>
/// If the device/browser will reload the page on return from the BankID app.
/// </summary>
/// <returns></returns>
public bool DeviceWillReloadPageOnReturnFromBankIdApp { get; }
}
}
Loading

0 comments on commit 2fea270

Please sign in to comment.