Valence API that replaces the older WS UserManagementService - desire2learn

One of our integrations uses the D2LWS UserManagementService to convert a username to userId. We receive the username, firstname and lastname of the student when they click through an LTI request, but we need the numeric userId for some of the other Valence API calls.
We would like to reduce our dependency on the D2LWS before they are retired, so we are wondering if there is an equivalent Valence API call that can be used to do this conversion?

There are many ways for a client application to fill out its understanding of an LMS user identity's properties. It is also noteworthy to remember that the D2LWS platform is essentially optimized for service-to-service level operational trust, while the newer Valence platform is optimized for user-to-service operational trust -- this means that all Valence calls must happen in the context of some real, authenticated LMS user account (in the sense that in order to make calls, the client application must first request to acquire a user ID/Key pair for an authenticated user).
If your client service will always be contacted or prompted by the LMS with an LTI launch, then you will have enough capacity from that launch to begin (please see this detailed topic on combining Valence calls with LTI around our Remote Plugin service). There should be a real LMS user that would have initiated that launch somehow, from a logged-in LMS session. Therefore, after the LTI launch, your service can turn right around and make a call to the LMS to request user tokens for the currently auth'd user and this user should almost certainly be the LTI-launching user.
Typically, for services that get contacted from an LTI launch and then want to use Valence, we recommend that you establish a user context immediately after the launch and make a whoami call: this can serve multiple purposes -- it can establish that you have a dependable set of user tokens you can use to make Valence calls on behalf of the launching user, and you can use the information retrieved in the WhoAmIUser data structure to assist in filling out the context of your user identity.
For your particular purposes, the WhoAmIUser data structure contains the first name, last name, unique name (user name), and LMS profile identifier for the launching user, as well as the LMS user identifier (Identifier) property that you can use in the context of other Valence calls should you need to. However, you should also strongly consider a shift to the user-to-service approach: when all the calls take place within the context of a particular user, you may discover that your best route is employing all the "my" routes to fill out the user experience you present to a user -- keep in mind that the user's credentials you employ with your Valence API calls restrict your access to functionality and data exactly as that user would be restricted in the course of his or her normal interactions with the LMS through its web UI.

Related

Can I use the same AdWords developerToken and clientCustomerId for different accounts?

I am making a web application that will automate some actions on Google AdWords. The web application can be used by anyone that has an AdWords account.
I am a bit puzzled by the AdWords API, as it is a different from other Google APIs, in terms that it needs two additional config parameters: developerToken and clientCustomerId, a per their documentation:
https://developers.google.com/adwords/api/docs/guides/first-api-call
When constructing the AdWordsClient object, I need to provide the developerToken and clientCustomerId, in order to push data to AdWords.
My question is whether these two parameters (developerToken, clientCustomerId) need to be different for each user that will use my web application?
It seems that I am able to post data to different accounts with an unrelated developerToken, which does not make sense.
Can I get the clientCustomerId from an API endpoint, so I don't require my users to manually input tokens and ids to the web app, and do the complete authentication with oAuth?
My code is working, I am asking more of the philosophy why I need these two parameters, and if I can avoid asking the user to manually copy them from the AdWords dashboard into my application?
The developer token identifies a given Adwords API developer and is used for RMF enforcement, rate limiting and the like. As you mentioned, this is different from other Google APIs, which I think has to do with the fact that it's not a publicly available API. You always have to use the developer token that was given to you as part of your API sign-up process and are not allowed to use another developer's one (thus there's no possibility to have a user of your application enter it on their own).
The clientCustomerId parameter refers to the specific Google Ads account that you want to interact with. As a given user (identified by the OAuth2 access token that you include in your request) might have access to a whole lot of different accounts, this always needs to be included.
As for how to obtain a list of accessible account given a user's credentials, you can use the CustomerService.getCustomers endpoint for that purpose. Quoting the docs, it will "return details of all the customers directly accessible by the user authenticating the call."

Restrict Microsoft Graph Service Account / Client Credentials

I'm developing an application on Microsoft Graph that runs as a daemon, and needs access to many accounts. As a result, I'm using a service account, also known as client credentials (using this method).
I can request the proper scope (calendars.readwrite) however as far as I can see, I cannot restrict to which calendars I have access. In my case, I only need access to the meetingroom calendars, and I'm afraid that organisations will not allow my application if I can also read and write from/to the CEO's calendar.
Is there any way (either while creating the app, or during/after giving admin consent) to restrict my app to only a subset of calendars? Or should I approach this problem differently and (e.g.) not use a service account in the first place?

Cutting short on the social login flow

Note: This is the first time I'm trying to implement a social login API, so thanks for bearing with me and helping me out!
I am developing a web application and I have a login and registration system already developed. Now, I am thinking of adding Facebook and Google+ login - with a backend. I went through their docs and other tutorials and they require to implement considerably a lot of things.
But, since I have a registration system already, I thought of doing something like this:
Have the social login buttons on the login page.
When the user clicks on a social login button and authorizes the app, the user data is returned from Google+, for example.
Now, instead of proceeding with the OAuth procedure like getting the user ID, secret ID and contacting their server from my server for token verification and getting data, is it possible to just use the data returned (after the user authorizes) and do the normal registration with the registration system that I already have?
These are the advantages that I see in doing this:
No need of extra code or database fields like token ID, etc.
User can add a password to their account whenever they want and login to the site or access their account by logging in through Facebook or Google+ given that they use the same email ID.
It's enough to use the social login providers' API once - the first time the user logs in (which technically registers the user to the site).
I know the advantages are the same when following the full OAuth2 implementation, but what difference does it make?
Now my questions are:
Is it OK to cut short on the social login as mentioned above?
Will I be losing any obvious advantage doing so (given that I already have a registration system in place)?
If yes, is anyone else cutting short on the flow in their website?
The system proposed by you has certain flaws, especially security related flaw. I would give you to the point answer:
You will send data from client after getting it from google+ or other provider and use your registration process implicitly.
This approach is wrong as I myself as an attacker can send you the data from google+ using my clientid for an app. Will you register or login using the info I am sending? I can pretend to be anyone in your system if you do that.
Is it OK to cut short on the social login as mentioned above?
Will I be losing any obvious advantage doing so (given that I already have a registration system in place)?
If yes, is anyone else cutting short on the flow in their website?
No. (see the reason above).
No. You won't be losing advantage as you already have system in place. Most of the sites have a system in place for normal registration. They give oauth login by leveraging it. Some will say that the password is cumbersome or such, but all famous sites provide login and password including SO.
Now the question comes, how to simplify the oauth system given that you already have a system in place.
I recommend this(I would assume Google as a provider) flow with things starting with dot are what you need to do:
You have a Google login button.
User click on Google Button.
The User is redirected to the Google site.
The user gives you permission.
Google redirects and give you a token.
You can now send info and token to your server. (You need to send only token as backend will get info. Otherwise, a user with valid google+ token for your website can send you any info).
Backend verify token and match that "aud" is equal to your client id. Or it can happen via a library. You will need to give only your client id.
Backend get profile info from token in case of Google+(Name, email) while verifying which you can store as part of your registration process or login process if that email already exists. You can store google id of user also. This is useful as some provider like fb don't always provide email for every account. (For some fb don't give email but for majority of cases it give you the email.)
Backend send back session info or jwt token or any other time bounded process which tells that the user is login.
Your user can login via email also. If he isn't already registered then, then he will need to register. Otherwise, using forget, he can set password or from accounts settings he can set password.
You also need to be careful if the same user is connecting via a different provider, he need to have the same account in your system which you can handle via email.
Kevin,
Authentication is a complex procedure involving lot of measures to ensure security. Hence Web-application/ App developers, delegate this critical piece of work to Identity providers like Google, Microsoft, Facebook etc. These Identity providers are trusted by the app developers and more importantly the consumers trust them too.
Why do app developers provide third party/ social logins? Because, it gives the users of the app some advantages.
They don't have to create new account with the app and remember the new set of credentials. Instead they can use the same credentials they are using with the Identity provider, to gain access to the app. This is huge.
They don't have to trust the app completely, means how the sensitive information like passwords, security questions are handled in the app, as they are not providing any sensitive information directly on the app. Only needed public information is fed to the app from the Identity provider. This is huge too.
No need to worry about the system compromise and leak of sensitive information as all Open ID providers have better security policies in place. This gives consumers a high degree of confidence when using your system through third party logins.
"All the advantages you mentioned will be great for the app developers
at the cost of disadvantages to the consumers of the app."
Lets put the consumer disadvantages on the side and look at the advantages you mentioned:
No need of extra code or database fields like token ID, etc.
You still need code/setup to validate your own tokens. You have to add more logic to verify the external tokens, but the consumers will have the advantage of using the external providers like they are in any other application.
User can add a password to their account whenever they want and login to the site or access their account by logging in through Facebook or Google+ given that they use the same email ID.
This is little confusing as users may choose external provider, so they don't have to remember a new password. Also, the account validation process is different if you use external login vs id/password login. If you are willing to provide both, then you already have the system in place, to verify the account for external logins. Then your first advantage is void and you are better of using Open ID spec.
It's enough to use the social login providers' API once - the first time the user logs in (which technically registers the user to the site).
This approach adds confusion to the flow for consumers. They expect to see a login screen from third party provider for authentication (when they click on google+ or FB), but instead they see your login screen.
Instead of cut short approach, it would be worth to use the complete flow. You might add more logic to handle the token verification with external providers, but, actual complex logic of token validation is delegated to the external providers. This adds no confusion to the end user and they can trust your application easily through social id providers. Even though, users can authenticate through social Id providers, it is always a best practice to have the profile object of that user in your system (without the sensitive information like password).
Since you have your own registration process in place, this may not be a huge advantage. But, please look into the open source implementation of any of the Security Token Service (STS) providers, to see if you can borrow some of the features for validation external providers.
Please let me know if you have any questions.
Thank you,
Soma.

Can I get an LMS-specific or org-specific user identifier in a Desire2Learn LE LTI launch?

By default, an LTI launch sent from the D2L LE provides the user_id property to uniquely identify the user making the LTI launch; however, this user ID can't be directly used with the LMS or most other institution systems to refer to the user: it is specific to LTI launches. Can I configure the LTI launch to provide a way to identify the user that I can directly use with the LMS or with other organization services (such as an LMS user ID, or a user log-in name)?
You can configure an External Learning Tool in the Learning Environment to provide more information with LTI launches: the precise list properties that an external learning tool can include in an LTI launch are first governed by the security settings for the LMS as Tools Consumer Information (in the "Settings" page for the External Learning Tools management screen); assuming that the LMS is configured to let LTI launches provide a wide variety of properties, you can set the launch to include one or more of these bits of information:
Send user ID to tool provider
This sends the LTI user_id property in the LTI launch.
Send user name to tool provider
This sends the user's name information in the properties lis_person_name_given, lis_person_name_family, and lis_person_name_full.
Send user email to tool provider
This sends the user's email information in the lis_person_contact_email_primary property.
Send system username to tool provider
This sends the user's LMS UserName (the name that a user would log into the LMS with) as the ext_d2l_username property.
Send system Org Defined ID to tool provider
This sends the organization's defined identifier for the student in the ext_d2l_orgdefinedid property. This is often the institution's student or employee number for the LMS user.
Send system role to tool provider
This sends the LMS role ID for the launching user within the org unit context from the launch occurred, in the property ext_d2l_role.
If you need to get the LMS UserID value for a user, then you can try using the Valence Learning Framework APIs. Immediately upon LTI launch, make a call to the APIs to retrieve a set of user tokens back to the launching domain; this should fetch you the user tokens for the launching user (who must currently have an current logged-in session with the LMS). You can then use a whomai call to verify that the user is who you think she is (by comparison to the bits of information from the LTI launch), or to fetch that user's LMS UserID property.

Using google/twitter/linkedIn authentication in iOS/Node application

I'm trying to work out the best architecture for a couple of apps I'm developing.
In both apps I want to utilise google/twitter/LinkedIn/etc to provide authentication of a users identity. The app is composed of an iOS app which has an option to send data to a server which I'm writing in node.js.
I want to utilise either OAuth or OpenId to handle identifying a user against the above servers so that I don't have to put in an authentication system of my own. In other words, allowing users to re-use their ids when choosing to upload data.
I should also note that apart from identifying a user, obtaining a name and email address, I have not intention of using any of their APIs at this time.
I think I have two options:
Place the Authorisation code in the iOS client and transmit some sort of key to the server with the data which it can then verify.
Keep the iOS client fairly dumb, and handle authorisation from the node server.
I'd probably prefer the second option because it means I could centralise authentication and be able to support a web site as well. That's my current theory.
Can anyone who has done something like this give me some pointers as to the pros and cons, OAuth or OpenId, or links to some examples?
In our previous app we opted for a combination of the two approaches. We wanted to centralize our user data on our server in the event we needed to make future API calls on those services. We also wanted the native oAuth experience for the user on the client. Ie: on Android and iOS, the developer can have single sign-on / authorization run through the native Facebook app (if available), vs. popping-up a webview that serves the 'Approve' dialog. It's a better user experience in my opinion. Also for Twitter, the oAuth process may require a PIN code to be entered in the callback which should probably be handled on the client side.
You can pass the access token retrieved by the client to the server for storage and later use if you intend on making additional API calls on these services, provided you expect the token to be long-lived (ie: offline-access permission on FB).
In any case this is mostly a user experience decision.

Resources