Desire2Learn API Authenticate User to System PHP - desire2learn

I have my APP ID / APP Key and using the PHP sample file I authenticate against our install of D2L. I receive back the UserID and UserKey to the sample page. I authenticate against the system with my Admin userid and password at this point, not a specific account for this. I can perform the WhoAmI and a couple other things, however, I'm looking at how I can authenticate a specific user into the system at this point for SSO? We have a custom portal and I authenticate users from it to our Angel LMS now. I'm looking to do that for D2L, authenticate the user that the portal has already validated and pass them into D2L My Home page. I have worked with a variety of API's over the years, but this one has been difficult and documentation seems limited. Any help would be appreciated.

If I understand you correctly, currently your LMS users employ the Angel LMS as an identity provider (i.e. it actually authenticates the users), and then the D2L LMS consumes that IDP's service in order to authenticate a user? D2L does support use of the Valence Learning Framework APIs when the D2L LMS is using another, third-party, service as an IDP, but the environment configuration can be somewhat tricky.
Essentially, the entry point for API authentication (the first step that an API client must take to get a set of user keys) calls an URL in the D2L LMS that then re-directs to the procedure to log in the user, passing a ?target= parameter containing the callback URL that the calling client provided when first requesting the user tokens.
Thus, in order for the SSO using a third party IDP to work for an API caller, that target parameter needs to be passed along in each stage of the user authentication chain, properly URL-encoded at each stage. The Valence documentation does provide an overview of this process.
If your particular LMS needs differ from one of the standard user-authentication scenarios, it's probably good to have your LMS Admins contact D2L's customer support desk and open an incident with them, specifically explaining that you would like to ensure that your LMS environment using third-party user authentication can be properly set up to use the Valence Learning Framework APIs.

Related

How do you implement the new DocuSign OAuth2.0 SOBO using eSignature SDK?

I'm in the process of converting an internal C# API that uses a legacy SOBO integration to one that uses OAuth 2.0 as required by DocuSign. The legacy application makes all requests to DocuSign using DocuSign credentials of an application user (a non-person) and injects SOBO data (email address) in the appropriate header when we need to generate an embedded sending URI and have it appear that the envelope was sent by a real person without using their credentials.
I have successfully converted another (non-SOBO) internal API using JWT grant, but I do not know how replicate the SOBO dependent workflow. Have read Matt King's article "From the Trenches: OAuth 2.0 and the new SOBO", but still a bit confused. I know how to extract userId from email address as mentioned in the article, but not sure what do with it. Similar to my legacy application, I am using a application user to get consent and ask for JWT token without prompting internal users for their consent. Is this still possible using OAuth 2.0?
Happy to help here. Once you've retrieved the user's apiUserName / userId you'll want to add it into the JWT assertion's sub line.
When you go to generate the token, if consent has not been provided by or for the user, our system will send back an error of "Consent_Required." See https://www.docusign.com/blog/developers/oauth-jwt-granting-consent for different methods of granting consent.
For individual consent, the user needs to go to a specific URL containing your clientId, redirectUri, and some additional scopes. If they hadn't previously consented to the scopes in your OAuth request they will be prompted to do this once. You can confirm consent has been applied by having them visit the same link afterwards, which will send them directly to your redirectUri.
Domain consent works a little differently -- you need to have an organization, a claimed domain, and the users you're providing consent on behalf of need to have an email address that is part of that claimed domain.
Happy to connect and walk you through it -- if you can open a ticket at support.docusign.com and in the details request they reach out to me I should be able to have the case transferred and work with you from there.
Regards,
Matt King

Is it okay to use client credentials grant type for authentication of a WEB API going to be consumed by SailPoint(IAM)

I have an old windows application written in VB.NET with SQL server backend. Currently the new user additions, deletion, adding entitlements etc. are managed by an old approval workflow system. After getting approvals, the user details and entitlements are inserted in to the SQL server database table manually.
I am trying to integrate this application with the SailPoint's Identity and access management. So the new user addition, deletion update and adding entitlements etc will be done through Sailpoint. For this, I would require to create a WEB API which can be called by Sailpoint and expose the functionalities(add user/delete user/add entitlements). The only consumer to this API is SailPoint.
I am new to OAuth and below are the grant types that I came across. But not sure which one I should be using in this particular scenario.
1.Implicit Grant
2.Resource Owner Password Credentials Grant
3.Client Credentials Grant
4.Authorization Code Grant
I have done research on the different authentication methods that we can use to secure the web api. But still confused on which one to apply in this scenario as this new web api is going to be made available in internet.
I already tried developing a POC with the OAuth 2.0 with password grant type referring this article. But when I read articles in the internet I found that the password grant type is not that secure and is deprecated.
Could you please advise on which grant type(client credentials/authorization code/implicit) to use in this scenario. I believe authorization code is used when the user is directly trying to access the API. In this scenario, SailPoint will be calling the API in the backend programmatically when they insert a new user in their UI.
I think it's a good approach to use client credentials in this case because the communication between IIQ and your Web API can be considered an API-to-API communication, I mean, IIQ is acting on behalf of itself in this communication.
See this article for more details - https://dzone.com/articles/four-most-used-rest-api-authentication-methods (bold part by myself)
OAuth 2.0 provides several popular flows suitable for different types
of API clients:
Authorization code — The most common flow, it is mostly used for
server-side and mobile web applications. This flow is similar to how
users sign up into a web application using their Facebook or Google
account.
Implicit — This flow requires the client to retrieve an
access token directly. It is useful in cases when the user’s
credentials cannot be stored in the client code because they can be
easily accessed by the third party. It is suitable for web, desktop,
and mobile applications that do not include any server component.
Resource owner password — Requires logging in with a username and
password. In that case, the credentials will be a part of the request.
This flow is suitable only for trusted clients (for example, official
applications released by the API provider).
Client Credentials —
Intended for the server-to-server authentication, this flow describes
an approach when the client application acts on its own behalf rather
than on behalf of any individual user. In most scenarios, this flow
provides the means to allow users to specify their credentials in the
client application, so it can access the resources under the client’s
control.

How to implement OpenID Connect authentication with 3rd party IDPs in a microservices architecture

For the past 10+ days I've read an watched ALL the content I could find on understanding OAuth2 and OpenID Connect, only to find that many people disagree on the implementation, which really confuses me.
To my understanding, all the articles and examples I found assume you want access to eg. google calendar, profile info or emails if you eg. login with google, but I do NOT need to access other than my own API's - I only want to use Google, Facebook etc for logging in, and getting an id which I can link to my user in my own database - nothing more than that.
I'll try illustrate my use case and use that as an example.
A note on the diagram: the Authentication service could probably be built into the API Gateway - not that i matters for this example, since this is not about "where to do it", but "how to do it the best way" possible, for an architecture such as mine, where it's used for my own API's / Microservices, and not accessing Google, Facebook etc. external API's
If you can understand what I'm trying to illustrate with this diagram above, please tell me if I've misunderstood this.
The most basic requirements for this architecture you see here are:
Users can login with Google, Facebook, etc.
The same login will be used for all micro-services
OpenId user will have a linked account in the database
User access is defined in my own db, based on groups, roles and permissions
I do not intend to use external API's after the user is authenticated and logged in. No need for ever accessing a users calendar, email etc. so I really just need the authentication part and nothing else (proof of successful login). All user access is defined in my own database.
So a few fundamental questions comes to mind.
First of all, is OpenID Connect even the right tool for the job for authentication only (I'll have no use for authorization, since I will not need read/write access to google / facebook API's other than getting the ID from authenticating)?
People generally do not agree on whether to use the ID or Access token for accessing your own API's. As far as I understand the ID token is for the client (user-agent) only, and the access token is for eg. accessing google calendar, emails etc.... External API's of the OpenID Provider... but since I'll only be accessing my own API's, do I event need the access token or the ID token - what is the correct way to protect your own API's?
If the ID token is really just for the client, so it can show eg. currently logged in user, without going to the DB, I have 0 use for it, since I'll probably query the user from from the db and store it in redux for my react frontend app.
Dilemma: To store user details, groups, roles and permission inside JWT or not for API authorization?
By only storing the user identifier in the token, it means that I always allow authenticated users that has a valid token, to call endpoints BEFORE authorization and first then determine access based on the db query result and the permissions in my own database.
By storing more data about the user inside the JWT, it means that in some cases, I'd be able to do the authorization / access (group, role, permission) check before hitting the API - only possible with user info, groups, roles and permission stored inside a JWT issued upon login. In some cases it would not be possible due to eg. the CMS content access permissions being on a per-node level. But still it would mean a little better performance.
As you can see on the diagram I'm sending all API requests through the gateway, which will (in itself or with an authentication service) translate the opaque access token into some JWT with an identifier, so I can identify the user in the graph database - and then verify if the user has the required groups, roles and permissions - not from an external API, but from my own database like you see on the diagram.
This seems like a lot of work on every request, even if the services can share the JWT in case multiple services should need to cross call each other.
The advantage of always looking up the user, and his permissions in the db, is naturally that the moment the user access levels change, he is denied/granted access immediately and it will always be in sync. If I store the user details, groups, roles and permission inside a JWT and persist that in the client localstorage, I guess it could pose a security issue right, and it would be pretty hard to update the user info, groups, roles and permissions inside that JWT?
One big advantage of storing user access levels and info inside the JWT is of course that in many cases I'd be able to block the user from calling certain API's, instead of having to determine access after a db lookup.
So the whole token translation thing means increased security at the cost of performance, but is is generally recommended and worth it? Or is it safe enough to store user info and groups, roles, permissions inside the JWT?
If yes, do I store all that information from my own DB in the ID Token, Access token or a 3rd token - what token is sent to the API and determines if the user should be granted access to a given resource based on his permissions in the db? Do I really need an access token if I don't need to interact with the ID providers API? Or do I store and append all my groups, roles, permissions inside the ID token (that doesn't seem clean to me) issued by OpenID connect, and call the API and authorize my own API endpoints using that, even if some say you should never use the ID token to access an API? Or do I create a new JWT to store all the info fetched from my database, which is to be used for deciding if the user can access a given resource / API endpoint?
Please do not just link to general specs or general info, since I've already read it all - I just failed to understand how to apply all that info to my actual use case (the diagram above). Try to please be as concrete as possible.
Made another attempt to try and simply the flow:
The following answer does only apply for a OpenID Connect authentication flow with a 3rd party IDP (like Google). It does not apply for an architecture where you host your own IDP.
(There are some API gateways (e.g Tyk or Kong) which support OpenID Connect out of the box.)
You can use JWTs (ID token) to secure your APIs. However, this has one disadvantage. JWTs cannot be revoked easily.
I would not recommend this. Instead you should implement an OAuth2 authorization server which issues access tokens for your API. (In this case, you have two OAuth2 flows. One for authentication and one for authorization. The ID and access token from the IDP are used only for authentication.)
The following picture shows a setup where the API gateway and authentication/authorization server are two separate services. (As mentioned above, the authentication/authorization can also be done by the API gateway.)
The authentication flow (Authorization Code Grant) calls are marked blue. The authorization flow (Implicit Grant) calls are marked green.
1: Your web app is loaded from the app server.
2a: The user clicks on your login button, your web app builds the authorization URL and opens it. (See: Authorization Request)
2b: Because the user hasn't authenticated and has no valid session with your authorization server, the URL he wanted to access is stored and your authorization server responds with a redirect to its login page.
3: The login page is loaded from your authorization server.
4a: The user clicks on "Login with ...".
4b: Your authorization server builds the IDP authorization URL and responds with a redirect to it. (See: Authentication Request)
5a: The IDP authorization URL is opend.
5b: Because the user hasn't authenticated and has no valid session with the IDP, the URL he wanted to access is stored and the IDP responds with a redirect to its login page.
6: The login page is loaded from the IDP.
7a: The user fills in his credentials and clicks on the login button.
7b: The IDP checks the credentials, creates a new session and responds with a redirect to the stored URL.
8a: The IDP authorization URL is opend again.
(The approval steps are ignored here for simplicity.)
8b: The IDP creates an authorization and responds with a redirect to the callback URL of your authorization server. (See: Authentication Response)
9a: The callback URL is opened.
9b: Your authorization server extracts the authorization code from the callback URL.
10a: Your authorization server calls the IDP's token endpoint, gets an ID and access token and validates the data in the ID token. (See: Token Request)
(10b: Your authorization server calls the IDP's user info endpoint if some needed claims aren't available in the ID token.)
11a/b: Your authorization server queries/creates the user in your service/DB, creates a new session and responds with a redirect to the stored URL.
12a: The authorization URL is opend again.
(The approval steps are ignored here for simplicity.)
12b/+13a/b: Your authorization server creates/gets the authorization (creates access token) and responds with a redirect to the callback URL of your web app. (See: Access Token Response)
14a: The callback URL is opened.
14b: Your web app extracts the access token from the callback URL.
15: Your web app makes an API call.
16/17/18: The API gateway checks the access token, exchanges the access token with an JWT (which contains user infos, ...) and forwards the call.
A setup where the authorization server calls the API gateway is also possible. In this case, after the authorization is done, the authorization server passes the access token and JWT to the API gateway. Here, however, everytime the user infos change the authorization server has to "inform" the API gateway.
This is a very long question. But I believe most can be summarised by answering below,
To my understanding, all the articles and examples I found assume you want access to eg. google calendar, profile info or emails if you eg. login with google,
You do not necessarily use Access token (ID token in some occasions) to access the services offered by token issuer.You can consume tokens by your own APIs. What these Identity Providers (synonym to Authorization server, or IDP in shorthand) is to hold identities of end users. For example, typical internet have a Facebook account. With OAuth and OpenID Connect, the same user get the ability to consume your API or any OAuth/OIDC accepted service. This reduce user profile creation for end users.
In corporate domain, OAuth and OIDC serves the same purpose. Having a single Azure AD account lets you to consume MS Word as well as Azure AD's OIDC will issue tokens which can be used to Authorise against an in-house API or an third party ERP product (used in organization) which support OIDC based authentication. Hope it's clear now
A note on the diagram is that the Authentication service could probably be built into the API Gateway - not sure if that would be better?
If you are planning to implement an API gateway, think twice. If things are small scale and if you think you can maintain it, then go ahead. But consider about API managers which could provide most of your required functionalities. I welcome you to read this article about WSO2 API manger and understand its capabilities (No I'm not working for them).
For example, that API manager has built in authentication handling mechanism for OAuth and OIDC. It can handle API authentication with simple set of configurations. With such solution you get rid of the requirement of implement everything.
What if you can't use an API manager and has to do it yourself
OpenID Connect is for authentication. Your application can validate the id token and authenticate end user. To access APIs through API Gateway, I think you should utilise Access token.
To validate the access token, you can use introspection endpoint of the identity provider. And to get user information, you can use user-info endpoint.
Once access token is validated, API gateway could create a session for a limited time (ideally to be less or equal to access token lifetime). Consequent requests should come with this session to accept by API gateway. Alternatively, you can still use validated access token. Since you validated it at the first call, you may cache for a certain time period thus avoiding round trips to validations.
To validate user details, permission and other grants, well you must wither bind user to a session or else associate user to access token from API gateway at token validation. I'm also not super clear about this as I have no idea on how your DB logic works.
First Appreciate your patience in writing a very valuable question in this forum
we too have same situation and problem
I want to go through ,as images are blocked in our company in detail
Was trying to draw paralles to similar one quoted in the book
Advance API In Practise - Prabath Siriwerdena [ page 269]Federating access to API's Chapter. Definitely worth reading of his works
API GW should invoke Token Exchange OAUTH2.0 Profile to IDP [ provided the IDP should support TOken Exchange profile for OAUTH 2.0
The Absence of API Gateway , will result in quite bespoke development
for Access Control for each API Check
you land up in having this check at each of the api or microservice [ either as library which does work for you as a reusable code]
definitely will become a choking point.]

Consuming the Valence API as an application

According to the Valence Docs,
Valence Learning Framework API calls are all made in isolation, by a known application, and by a known LMS user.
If I want to build an application that has admin access, I'm guessing that I would have to make a "service account" that has admin access, and have my application use the API as that user.
How would I go about obtaining a userId and userKey for users that aren't real people, and only exist for the application to connect to the valence API?
Once you create a Service Account, you need to manually harvest the user tokens using a utility such as the API Test Tool (https://apitesttool.desire2learnvalence.com/) to authenticate with your LMS. You then need to store those keys securely, and configure your LMS to ensure the user tokens are long-lived. Many systems have a token timeout of 30 days, but when a headless integration is in place like the one you're proposing, it's often a good idea to make the timeout infinite. You can contact Desire2Learn Support to verify the timeout value for the user tokens.
There's a similar question that addresses this issue as well: Authenticaton Method for Desire2Learn REST API vs SOAP.

Does OAuth 2 specify a permanent identifier for a given user?

I've just been (re)reading Rob Conery's 2010 blog post OpenID is a Nightmare as part of some research into OpenID/OpenAuth. Ideally, I'm looking to use multiple OAuth providers linked to a single account, to provide resilience against the providers being unavailable - log in with Facebook, link your Twitter and Google accounts, and if next time you visit Facebook login isn't working it doesn't matter, you can use Twitter OR Google to get in and access your stuff - just as, in the real world, you can open a bank account with a passport, and withdraw money later using your driving license if your passport's not available.
One of Rob's primary concerns in his article is that there's no way to consistently identify a user who's using OpenID - somebody might log in with Google one day, buy a product, then come back and log in with Google a few days later and be unable to access the product they bought, because there's no unique identifier that's guaranteed to remain consistent between the two Google authentication calls.
I'm curious as to whether this has been addressed in OAuth 2.0 - either explicitly via the protocol spec, or via some implementation consensus amongst the major providers. Which field - if any - can I rely on not to change for the lifetime of a user's relationship with a particular OAuth provider?
As part of their OAuth2 for login process, Google provide a TokenInfo endpoint that is used to validate and provide information about the access_token that is obtained earlier in the process.
The token information includes userid:
"The value of this field is an immutable identifier for the logged-in user, and may be used when creating and managing user sessions in your application. This identifier is the same regardless of the client_id. This provides the ability to correlate profile information across multiple applications in the same organization."
which sounds like just the ticket (or perhaps token)!
userid is only present if the https://www.googleapis.com/auth/userinfo.profile scope was included in the access token request, so don't forget that.
Similarly, in the Facebook API you have access to the graph API once you've obtained an access token where you can get user data, including ID.
Twitter include the user_id in the access token response as part of their authentication API
If you're using OAuth in a .NET project this might be useful... I discovered today that WebMatrix 2 Beta includes OAuth2 clients for Facebook, Twitter, Windows Live, Google and Yahoo, and can be used from an MVC project. I'm told that you just need the WebMatrix.Security.dll and you're good to go. It's installed into C:\Program Files (x86)\Microsoft ASP.NET\ASP.NET Web Pages\v2.0\Assemblies. Although it's in beta and hidden away, it's a good way to get started and might make the the learning curve with the DotNetOpenAuth library a bit less steep.
OAuth 2.0 doesn't solve this - it's not an identity / SSO protocol.
However, OpenID Connect (built on OAuth 2.0) is. You may get lucky and get back the user's email address via OpenID Connect (see here - depending on scopes), or you may get back PPID's which should be unique to a given relying party. Either way - it should be possible.
Alternatively, SAML could be used. It supports many different flavors of user identifiers that would suit.

Resources