id4me_relying_party_api 0.5.0

Id4me Relying Party Api #

Id4me Relying Party Api provides easy integration of the Id4me login into your projects. Since Id4me is still in beta, the login process can change at any time and make this package unusable!

Table of Contents #

  1. Install
  2. Import
  3. Login Flow
  4. Exceptions
  5. Changelog
  6. Copyright and license

Install #

pubspec.yaml #

Update pubspec.yaml and add the following line to your dependencies.

dependencies:
  id4me_relying_party_api: ^0.5.0

Import #

Import the package with :

import 'package:id4me_relying_party_api/id4me_relying_party_api.dart';

Login Flow #

Basics #

The main class used is the Id4meLogon class. The package also contains many more classes that are used by the Id4meLogon class. View the Example for a detailed example on how to use the Id4meLogon.

Create login service #

The first step in the login flow is to create an instance of the login service class Id4meLogon with the necessery properties and claimsparameter. See the example on how to set them up.


Map<String, dynamic> properties = {
    Id4meConstants.KEY_CLIENT_NAME: "ID4me Login Demo",
    Id4meConstants.KEY_LOGO_URI: "https://domain.com/favicon.png",
    Id4meConstants.KEY_REDIRECT_URI: "https://domain.com/redirect"
};

Map<String, dynamic> claimsParameters = {
    Id4meConstants.KEY_CLAIM_EMAIL: {
      "required": true,
      "reason": "Needed to create the profile"
    },
    Id4meConstants.KEY_CLAIM_NAME: {
      "required": true,
      "reason": "Displayname in the user data"
    },
    Id4meConstants.KEY_CLAIM_GIVEN_NAME: {"required": true, "reason": ""},
};

Id4meLogon logon = new Id4meLogon(properties: properties, claimsParameters: claimsParameters);

Create Session Data #

The next step is to create the session data, that is needed throughout the hole login process. It fetches for example the DNS data and identity authority data.

Id4meSessionData sessionData;
try {
  sessionData = await logon.createSessionData(domain, true);
} on DnsResolveException {
  // Handle DnsResolveException
} on IdentityAuthorityDataFetchException {
  // Handle IdentityAuthorityDataFetchException
} on Id4meIdentifierFormatException {
  // Handle Id4meIdentifierFormatException
} on DnsDataNotParseableException {
  // Handle DnsDataNotParseableException
} catch (e) {
  // Handle any other exception
}

Build Authorization Url #

The data from the DNS can now be used to create an authentication url to which the user is routed.

String authorizationURL = logon.buildAuthorizationUrl(sessionData);

Authenticate #

After the user has been redirected by the Identity Authority, the code, given as a query parameter in the redirect url, can be used to authorize with the Identity Agent.

The redirect url could look like this : https://domain.com/redirect?code=DKYPkDfkH0cLw3_NmS6IGQ.BPA4gUtfLh0gljqQ3wJNVw&state=authorize

try {
  await logon.authenticate(sessionData, code);
} on BearerTokenFetchException {
  // Handle BearerTokenFetchException
} on BearerTokenNotFoundException {
  // Handle BearerTokenNotFoundException
} catch (e) {
  // Handle any other exception
}

Fetch UserInfo #

After successful authorization, the requested user data can be queried.

Map<String, dynamic> info;
try {
  info = await logon.fetchUserinfo(sessionData);
} on MandatoryClaimsException {
  // Handle MandatoryClaimsException
} on UserInfoFetchException {
  // Handle UserInfoFetchException
} catch (e) {
  // Handle any other exception
}

Exceptions #

The login service can throw several id4me specific exceptions throughout the login flow. View the example for the right time to catch them.

Id4meIdentifierFormatException #

If the ID4me identifier has the wrong format, an Id4meIdentifierFormatException is thrown.

DnsResolveException #

The DnsResolveException is thrown when something unexpected happens while trying to fetch the _openid TXT record for the given id4me login.

DnsDataNotParseableException #

[DnsDataNotParseableException]/lib/src/model/exception/DnsDataNotParseableException.dart) is thrown if the Id4meDnsData could not be parsed from the dns record value.

IdentityAuthorityDataFetchException #

If it is not possible to fetch the data for configured Identity Authority, an IdentityAuthorityDataFetchException is thrown.

BearerTokenFetchException #

A BearerTokenFetchException is thrown when something unexpected happens while trying to fetch the bearer token from the Idenity Agent.

BearerTokenNotFoundException #

If the response from the Idenity Agent does not contain a bearer token the BearerTokenNotFoundException is thrown.

UserInfoFetchException #

When something unexpected happens while trying to fetch the userinfo from the Identity Agent, an UserInfoFetchException is thrown.

MandatoryClaimsException #

If the UserInfo does not contain all claimes that are marked as required, the MandatoryClaimsException is thrown.

Changelog #

For a detailed changelog, see the CHANGELOG.md file

MIT License

Copyright (c) 2019 Ephenodrom

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Changelog #

[0.5.0] - 2019-05-15

  • Add error handling

[0.4.0] - 2019-05-07

  • Convert Claimsparameter to Map<String,dynamic>

[0.3.2] - 2019-05-06

  • Improve code

[0.3.0] - 2019-05-06

  • Improve documentation

[0.2.0] - 2019-05-03

  • Improve code

[0.1.0] - 2019-05-03

  • Initial release

example/main.dart

import 'dart:io';

import 'package:id4me_relying_party_api/id4me_relying_party_api.dart';
import 'dart:convert';

void main() async {
  Map<String, dynamic> properties = {
    Id4meConstants.KEY_CLIENT_NAME: "ID4me Demo",
    Id4meConstants.KEY_LOGO_URI:
        "https://www.androidpit.com/img/logo/favicon.png",
    Id4meConstants.KEY_REDIRECT_URI:
        "https://www.androidpit.com/id4me/demo-callback",
    Id4meConstants.KEY_DNS_RESOLVER: "8.8.8.8",
    Id4meConstants.KEY_DNSSEC_REQUIRED: false
  };

  Map<String, dynamic> claimsParameters = {
    Id4meConstants.KEY_CLAIM_EMAIL: {
      "required": true,
      "reason": "Needed to create the profile"
    },
    Id4meConstants.KEY_CLAIM_NAME: {
      "required": true,
      "reason": "Displayname in the user data"
    },
    Id4meConstants.KEY_CLAIM_GIVEN_NAME: {"required": true, "reason": ""},
  };

  Id4meLogon logon = new Id4meLogon(
      properties: properties, claimsParameters: claimsParameters);

  print("Please enter your ID4me identifier: ");
  String domain = stdin.readLineSync();

  print("Creating session data...");

  Id4meSessionData sessionData;
  try {
    sessionData = await logon.createSessionData(domain, true);
  } on DnsResolveException {
    // Handle dns resolving exception
  } on IdentityAuthorityDataFetchException {
    // Handle Identity Authority data fetch exception
  } on Id4meIdentifierFormatException {
    // Handle Id4meIdentifierFormatException
  } catch (e) {
    // Handle any other exception
  }

  print("Building authorization URL...");
  String authorizationURL = logon.buildAuthorizationUrl(sessionData);

  print("authorizationURL = $authorizationURL");

  print("Please enter the code: ");
  String code = stdin.readLineSync();

  print("Verifying code...");
  try {
    await logon.authenticate(sessionData, code);
  } on BearerTokenFetchException {
    // Handle error while fetching bearer token
  } on BearerTokenNotFoundException {
    // Handle missing bearer token
  } catch (e) {
    // Handle any other exception
  }

  print("Retrieving user info...");
  Map<String, dynamic> info;
  try {
    info = await logon.fetchUserinfo(sessionData);
  } on MandatoryClaimsException {
    // Handle missing mandatory claims
  } on UserInfoFetchException {
    // Handle user info fetch exception
  } catch (e) {
    // Handle any other exception
  }
  print(json.encode(info));
}

Use this package as a library

1. Depend on it

Add this to your package's pubspec.yaml file:


dependencies:
  id4me_relying_party_api: ^0.5.0

2. Install it

You can install packages from the command line:

with pub:


$ pub get

with Flutter:


$ flutter pub get

Alternatively, your editor might support pub get or flutter pub get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:


import 'package:id4me_relying_party_api/id4me_relying_party_api.dart';
  
Popularity:
Describes how popular the package is relative to other packages. [more]
7
Health:
Code health derived from static analysis. [more]
97
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
100
Overall:
Weighted score of the above. [more]
53
Learn more about scoring.

We analyzed this package on Aug 19, 2019, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.4.0
  • pana: 0.12.19

Platforms

Detected platforms: Flutter, web, other

No platform restriction found in primary library package:id4me_relying_party_api/id4me_relying_party_api.dart.

Health suggestions

Fix lib/src/Id4meLogon.dart. (-2.48 points)

Analysis of lib/src/Id4meLogon.dart reported 5 hints:

line 31 col 7: DO use curly braces for all flow control structures.

line 155 col 9: DO use curly braces for all flow control structures.

line 162 col 9: DO use curly braces for all flow control structures.

line 171 col 7: DO use curly braces for all flow control structures.

line 174 col 7: DO use curly braces for all flow control structures.

Fix lib/src/model/Id4meResolver.dart. (-0.50 points)

Analysis of lib/src/model/Id4meResolver.dart reported 1 hint:

line 34 col 19: Don't explicitly initialize variables to null.

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.0.0-dev.68.0 <3.0.0
basic_utils ^1.1.1 1.6.0
crypto ^2.0.6 2.1.1+1
jose ^0.1.2 0.1.2
logging ^0.11.3+2 0.11.3+2
uuid ^2.0.1 2.0.2
Transitive dependencies
async 2.3.0
built_collection 4.2.2
built_value 6.7.0
charcode 1.1.2
collection 1.14.12
convert 2.1.1
crypto_keys 0.1.0
fixnum 0.10.9
http 0.12.0+2
http_parser 3.1.3
json_annotation 2.4.0 3.0.0
matcher 0.12.5
meta 1.1.7
path 1.6.4
pedantic 1.8.0+1
pointycastle 1.0.1
quiver 2.0.5
source_span 1.5.5
stack_trace 1.9.3
string_scanner 1.0.5
term_glyph 1.1.0
typed_data 1.1.6
Dev dependencies
test >=0.12.42 <2.0.0