Custom OAuth2 Service

Custom OAuth2 Service

by Michael Knight -
Number of replies: 5

I'm trying to setup SSO with a private CMS vendor who provides support for OAuth2 and member data via REST API. I'd like to use the custom service option in the OAuth 2 Service section (3.3.3) but the vendor uses Basic Authentication for token endpoints and I have to use their REST API service to pull user info. The conventional endpoints won't work without modification in my case.  For now I have modified the core directly to supplement these changes by adding the following:

lib/filelib.php

curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($curl, CURLOPT_USERPWD, "myapiusername:myapipassword"); 

this fixes my http basic authentication issue


/lib/classes/oauth2/client.php
Modified get_userinfo() to use the vendors API Rest service using curl directly to pull in all the fields needed for mapping. The rest of the set up is pretty much similar to the google, facebook, microsoft configuration.

Is there a way to do this without modifying the core or creating an auth plugin from scratch?


Average of ratings: -
In reply to Michael Knight

Re: Custom OAuth2 Service

by Jan Dageförde -

Hi,

regarding Basic Auth: I need that, too, which is why I filed MDL-59512. I also added a patch that works (for now, but far from production ready smile ). Note that I patched lib/oauthlib.php instead of lib/filelib.php, which is at least less likely to affect curl uses other than OAuth.

Regarding the definition of an OAuth Service: At [wwwroot]/admin/tool/oauth2/issuers.php you should be able to define issuers (I suppose you already have that) as well as endpoints and field mappings (for userinfo). I think the latter two are rather hidden, but they are links in the table of  [wwwroot]/admin/tool/oauth2/issuers.php. This way I was able to create arbitrary mappings of JSON responses to Moodle fields. Even nested JSON objects work; hierarchy levels are delimited by "-" (e.g. "user-mail" corresponds to a "mail" attribute in the object located at "user").

Cheers,
Jan

In reply to Jan Dageförde

Re: Custom OAuth2 Service

by Michael Knight -

Thanks for your input Jan.  I'm sure that Basic Auth can easily be implemented using an enable endpoint authentication checkbox with login fields. This way Google, Microsoft and others can operate the way they currently do.  

I'm not too happy about modifying the core and I'll work to refine my hack with  some logic so that my changes have less system wide impact. 

It would be great if we could introduce a way to hook into the client userinfo process without having to write a plugin from scratch. This would greatly maximize the usefulness of the custom oauth2 service.

Mike

In reply to Michael Knight

Re: Custom OAuth2 Service

by Jan Dageförde -

Apart from getting Basic Auth to work (which I very much hope will be introduced in core), what core hacks do you need? Are you sure you need to modify get_userinfo(), i.e. what modifications did you make? Maybe there is an easier way smile

By the way, if you have a tracker account, please vote for the Basic Auth ticket (MDL-59512) to indicate that it is relevant to your use case as well. Maybe you could also describe your situation there, that would be even more helpful to show the relevance. Thanks!

In reply to Jan Dageförde

Re: Custom OAuth2 Service

by Michael Knight -

Voted!  My issue with userinfo is that my provider doesn't offer a usable set of userinfo fields out of the box. Only the member_id of the individual logging in. The intention was to use the member_id received with their official REST api following oauth2 authentication.  I added a block of code to pull in the member fields I need using their api and populated the userinfo json fields. Not pretty but works great.

In reply to Michael Knight

Re: Custom OAuth2 Service

by Jan Dageförde -

Would it be possible to completely replace the userinfo endpoint with the other REST endpoint you are mentioning? That should work, as you can change the endpoint URL that Moodle uses – unless that REST endpoint is missing some other data...