Giter VIP home page Giter VIP logo

guardian.swift's Introduction

Guardian.swift (iOS)

CircleCI Coverage Status Version License Platform Carthage compatible Swift 4.1

Guardian is Auth0's multi-factor authentication (MFA) service that provides a simple, safe way for you to implement MFA.

Auth0 is an authentication broker that supports social identity providers as well as enterprise identity providers such as Active Directory, LDAP, Google Apps and Salesforce.

This SDK allows you to integrate Auth0's Guardian multi-factor service in your own app, transforming it in the second factor itself. Your users will get all the benefits of our frictionless multi-factor authentication from your app.

Requirements

iOS 10+ and Swift 4.1 is required in order to use Guardian.

Before getting started

To use this SDK you have to configure your tenant's Guardian service with your own push notification credentials, otherwise you would not receive any push notifications. Please read the docs about how to accomplish that.

Install

CocoaPods

Guardian.swift is available through CocoaPods. To install it, simply add the following line to your Podfile:

pod 'Guardian', '~> 1.4.0'

Carthage

In your Cartfile add this line

github "auth0/Guardian.swift" ~> 1.4.0

Usage

Guardian is the core of the SDK. To get things going you'll have to import the library:

import Guardian

Set the auth0 domain for your tenant:

let domain = "https://<tenant>.<locality>.auth0.com/appliance-mfa"

alternatively you can use the custom domain if you configured one:

let domain = "https://<custom>/appliance-mfa"

Enroll

An enrollment is a link between the second factor and an Auth0 account. When an account is enrolled you'll need it to provide the second factor required to verify the identity.

For an enrollment you need the following things, besides your Guardian Domain:

  • Enrollment Uri: The value encoded in the QR Code scanned from Guardian Web Widget or in your enrollment ticket sent to you, e.g. by email.
  • APNS Token: Apple APNS token for the device and MUST be a Stringcontaining the 64 bytes (expressed in hexadecimal format)
  • Signing & Verification Key: A RSA (Private/Public) key pair used to assert your identity with Auth0 Guardian

In case your app is not yet using push notifications or you're not familiar with it, you should check their docs.

after your have all of them, you can enroll your device

Guardian
        .enroll(forDomain: "{YOUR_GUARDIAN_DOMAIN}",
                usingUri: "{ENROLLMENT_URI}",
                notificationToken: "{APNS_TOKEN}",
                signingKey: signingKey,
                verificationKey: verificationKey
                )
        .start { result in
            switch result {
            case .success(let enrolledDevice):
                // success, we have the enrollment device data available
            case .failure(let cause):
                // something failed, check cause to see what went wrong
            }
        }

On success you'll obtain the enrollment information, that should be secured stored in your application. This information includes the enrollment identifier, and the token for Guardian API associated to your device for updating or deleting your enrollment.

Signing & Verification Keys

Guardian.swift provides a convenience class to generate a signing key

let signingKey = try DataRSAPrivateKey.new()

this key only exists in memory but you can obtain its Data representation and store securely e.g. in an encrypted SQLiteDB

// Store data
let data = signingKey.data
// performthe storage

// Load from Storage
let loadedKey = try DataRSAPrivateKey(data: data)

But if you just want to store inside iOS Keychain

let signingKey = try KeychainRSAPrivateKey.new(with: "com.myapp.mytag")

It will create it and store it automatically under the supplied tag, if you want to retrieve it using the tag

let signingKey = try KeychainRSAPrivateKey(tag: "com.myapp.mytag")

The tags should be unique since it's the identifier of each key inside iOS Keychain.

and for the verification key, we can just obtain it from any SigningKey like this

let verificationKey = try signingKey.verificationKey()

Allow a login request

Once you have the enrollment in place, you will receive a push notification every time the user has to validate his identity with MFA.

Guardian provides a method to parse the data received from APNs and return a Notification instance ready to be used.

if let notification = Guardian.notification(from: userInfo) {
    // we have received a Guardian push notification
}

Once you have the notification instance, you can easily allow the authentication request by using the allow method. You'll also need some information from the enrolled device that you obtained previously. In case you have more than one enrollment, you'll have to find the one that has the same id as the notification (the enrollmentId property).

When you have the information, device parameter is anything that implements the protocol AuthenticatedDevice

struct Authenticator: Guardian.AuthenticationDevice {
    let signingKey: SigningKey
    let localIdentifier: String
}

Local identifier is the local id of the device, by default on enroll UIDevice.current.identifierForVendor

Then just call

Guardian
        .authentication(forDomain: "{YOUR_GUARDIAN_DOMAIN}", device: device)
        .allow(notification: notification)
        .start { result in
            switch result {
            case .success:
                // the auth request was successfuly allowed
            case .failure(let cause):
                // something failed, check cause to see what went wrong
            }
        }

Reject a login request

To deny an authentication request just call reject instead. You can also send a reject reason if you want. The reject reason will be available in the guardian logs.

Guardian
        .authentication(forDomain: "{YOUR_GUARDIAN_DOMAIN}", device: device)
        .reject(notification: notification)
        // or reject(notification: notification, withReason: "hacked")
        .start { result in
            switch result {
            case .success:
                // the auth request was successfuly rejected
            case .failure(let cause):
                // something failed, check cause to see what went wrong
            }
        }

Unenroll

If you want to delete an enrollment -for example if you want to disable MFA- you can make the following request:

Guardian
        .api(forDomain: "{YOUR_GUARDIAN_DOMAIN}")
        .device(forEnrollmentId: "{USER_ENROLLMENT_ID}", token: "{ENROLLMENT_DEVICE_TOKEN}")
        .delete()
        .start { result in
            switch result {
            case .success:
                // success, the enrollment was deleted
            case .failure(let cause):
                // something failed, check cause to see what went wrong
            }
        }

What is Auth0?

Auth0 helps you to:

  • Add authentication with multiple authentication sources, either social like Google, Facebook, Microsoft Account, LinkedIn, GitHub, Twitter, Box, Salesforce, amont others, or enterprise identity systems like Windows Azure AD, Google Apps, Active Directory, ADFS or any SAML Identity Provider.
  • Add authentication through more traditional username/password databases.
  • Add support for linking different user accounts with the same user.
  • Support for generating signed Json Web Tokens to call your APIs and flow the user identity securely.
  • Analytics of how, when and where users are logging in.
  • Pull data from other sources and add it to the user profile, through JavaScript rules.

Create a free account in Auth0

  1. Go to Auth0 and click Sign Up.
  2. Use Google, GitHub or Microsoft Account to login.

Issue Reporting

If you have found a bug or if you have a feature request, please report them at this repository issues section. Please do not report security vulnerabilities on the public GitHub issue tracker. The Responsible Disclosure Program details the procedure for disclosing security issues.

Author

Auth0

License

This project is licensed under the MIT license. See the LICENSE file for more info.

guardian.swift's People

Contributors

andy317fe301f8c7 avatar artelas avatar crew-security avatar diegose avatar hzalaz avatar ionutmanolache-okta avatar jayhelton avatar joseluisdiaz avatar nikolaseu avatar sre-57-opslevel[bot] avatar widcket avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

guardian.swift's Issues

Privacy manifest for this library

Description

Provide a clear and concise description of the issue, including what you expected to happen.

Apple recently updated their Program Licence Agreement to add enforcement behind the new Privacy Report available in xcode (Section 3.3.9). Part of this requires SDK's to report any data collected or used using a privacy manifest as described here: https://developer.apple.com/documentation/bundleresources/describing_data_use_in_privacy_manifests

As far as I can tell, this is optional if the SDK does not contain any privacy-impacting operations/actions.

Can you confirm that this SDK does not require one?

Reproduction

Detail the steps taken to reproduce this error, what was expected, and whether this issue can be reproduced consistently or if it is intermittent.

Where applicable, please include:

  • Code sample to reproduce the issue
  • Log files (redact/remove sensitive information)
  • Application settings (redact/remove sensitive information)
  • Screenshots

No PrivacyInfo.xcprivacy found

Environment

Please provide the following:

  • Version of this library used: master
  • Version of the platform or framework used, if applicable:
  • Other relevant versions (language, server software, OS, browser):
  • Other modules/plugins/libraries that might be involved:

Turn off iOS HTTP cache

The iOS SDK for HTTP connections uses a coaching mechanism and stores data in the Cache.db. Looking at the Cache.db the user credentials are found. This is a security issue when the device is hacked.

Please turn off any caching on HTTP connections using the cache control.

Need a way to get the Guardian category needed to allow/deny outside the app

The category of the remote notification can be built like

 let acceptAction = UIMutableUserNotificationAction()
acceptAction.identifier = "com.auth0.notification.authentication.accept"
acceptAction.title = NSLocalizedString("Allow", comment: "Accept")
acceptAction.isDestructive = false


let rejectAction = UIMutableUserNotificationAction()
rejectAction.identifier = "com.auth0.notification.authentication.reject"
rejectAction.title = NSLocalizedString("Deny", comment: "Reject")
rejectAction.isDestructive = true

let category = UIMutableUserNotificationCategory()
category.identifier = "com.auth0.notification.authentication"
category.setActions([acceptAction, rejectAction], for: .default)
category.setActions([acceptAction, rejectAction], for: .minimal)

We can allow to customise the titles and probably provide also a method to perform the registration

let notificationTypes: UIUserNotificationType = [.badge, .sound]
let pushNotificationSettings = UIUserNotificationSettings(types: notificationTypes, categories: [category])
application.registerUserNotificationSettings(pushNotificationSettings)
application.registerForRemoteNotifications()

This is for pre iOS 10 so we might need to perform iOS 10 config too

Private constants as default arguments - Swift 4 Support

Problem

When adding Guardian to a project that uses Swift 4.x, there are several errors building Guardian pod. All of them refer to the fact that an internal constant (let) cannot be referenced from a default argument value.

The constant is:

let nonCachedSession: URLSession =  {
     let config = URLSessionConfiguration.default
     config.requestCachePolicy = .reloadIgnoringLocalCacheData
     config.urlCache = nil

     return URLSession.init(configuration: config)
}()

Guardian.swift line 25

And some of the places where it is used as default value are:

public func api(forDomain domain: String, session: URLSession = nonCachedSession) -> API {
    return api(url: url(from: domain)!, session: session)
}

Guardian.swift line 47

Workaround:

In the Pods project change the default language to Swift 3 (or below). 

Fix:

Make nonCachedSession public

Screenshots

Swift 3

captura de pantalla 2018-07-02 a la s 17 56 56

Swift 4.x

captura de pantalla 2018-07-02 a la s 18 10 55

iOS 10 notification support

Most examples show pre iOS 10 notification handling, with iOS 10 and the introduction of UserNotifications.framework there is a new API for requesting access to notification and also receiving them.

Support SwiftPM

Please do not report security vulnerabilities here. The Responsible Disclosure Program details the procedure for disclosing security issues.

Thank you in advance for helping us to improve this library! Your attention to detail here is greatly appreciated and will help us respond as quickly as possible. For general support or usage questions, use the Auth0 Community or Auth0 Support. Finally, to avoid duplicates, please search existing Issues before submitting one here.

By submitting an Issue to this repository, you agree to the terms within the Auth0 Code of Conduct.

Describe the problem you'd like to have solved

Currently cocoa pods and Carthage is supported. Modern projects use SwiftPM which is not supported.

Describe the ideal solution

Also support SwiftPM.

Alternatives and current work-arounds

If it is not possible for any reason, a description about how to integrate the sdk manually would be good including all it dependencies.

Additional context

-

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.