jimdigriz / freeradius-oauth2-perl

FreeRADIUS OAuth2 (OpenID Connect) using rlm_perl
GNU Affero General Public License v3.0
127 stars 35 forks source link

Small fixes to make it work with AzureAD in 2019 #5

Closed glauco76 closed 4 years ago

glauco76 commented 5 years ago

I know this project is quite old, but it works well and thus I thought of contributing with a couple small hints to make it work with the current version of AzureAD.

The setup information kinda works. The recent AzureAD UI is slightly different from the previous one, but there is a document from Microsoft explaining the differences here and is pretty straightforward.

The perl code needs some tweakings.

There are a couple lines rising errors in json decoding: This one:
my $j = decode_json $r->decoded_content; Needs to be changed to this: my $j = JSON->new->allow_nonref->decode($r->decoded_content);

Then, when a successful authentication has happened, microsoft AD apparently does NOT respond with a full JSON with all the fields required by this module, but only with the auth token. Therefore, the following lines need to be commented out because the received json simply does not contain token_type and access_token, but just token_id: unless (defined($j->{'token_type'} && $j->{'access_token'})) { &radiusd::radlog(RADIUS_LOG_ERROR, 'missing token_type/access_token in JSON response'); return RLM_MODULE_REJECT; } It should not be an issue because in case of unsuccessful auth the received JSON is completely different and only includes error codes. It is just a quick fix, probably needs some more exception handling, but so far worked for me.

jimdigriz commented 5 years ago

A client of mine needs me to help them with a DNS migration to Azure next month so when I am next in there I will get this fixed up (and some of the other issues); they already use AzureAD and I have an account in there (and an 802.1X/eduroam network) so I have no excuses ;)

Thank you for taking the time to flag up the issue, look into the problem and explain to me your fix, it is really appreciated.

glauco76 commented 5 years ago

Glad to help!

at this point, let me add the result of hours of fiddling and googling and headbanging to make everything work with Windows 10. I'll leave it here for future use

Let's start from the very beginning: The default installation of freeradius does NOT work with windows WPA supplicant, it simply fails the radius EAP tunnel setup process (does not respond to access-challenge sent from freeradius)

To solve this issue you will get a hint when reading here . This says that to make it work with Windows clients, the freeradius certificates need to have some specific extensions that Windows requires to work. The default freeradius installation will happily start using default certificates located in some example location, which do NOT have the extensions! You then have to create new certificates at first and then point to them in the mods-enabled/eap configuration file.

You do it like this:

When you start freeradius you will notice it asks you for the cert password you configured in the cnf files before

All of a sudden, the good old windows client happily goes on with the EAP handshake and the auth is magically done.

IMPORTANT NOTES:

krisztian-andre commented 5 years ago

I need to get Azure MFA working. Let me try to put together a test configuration. @glauco76 do you have in the meanwhile more info about the error?

krisztian-andre commented 5 years ago

I am not sure if this applies here, but for another app Azure MFA needed to be forced in an URI: https://stackoverflow.com/questions/51785256/how-to-make-oauth2-work-for-azure-active-directory-with-multi-factor-authenticat

jimdigriz commented 5 years ago

Maybe if you described:

  1. What are you trying to do
  2. How are you going about doing it
  3. What are you expecting to happen
  4. What is actually happening

I may then be able to provide some advice.

I have really no idea why you opened an issue or what the problem is you are facing?

Regards

On 3 October 2019 18:58:18 krisztian-andre notifications@github.com wrote:

I am not sure if this applies here, but for another app Azure MFA needed to be forced in an URI: https://stackoverflow.com/questions/51785256/how-to-make-oauth2-work-for-azure-active-directory-with-multi-factor-authenticat — You are receiving this because you commented. Reply to this email directly, view it on GitHub, or mute the thread.

krisztian-andre commented 5 years ago

I am trying to use freeradius to authorize my Azure AD users (who also have Azure MFA configured) for the use of vrious VPN and WIFI services that are utilizing RADIUS as an auth backend. I would like to use your freeradius module to achieve this and need to figure out how to get MFA working.

The issue I created is simply for porting the module to freeradius 3.0.

jimdigriz commented 5 years ago

I do not think this will work as the MFA support with Azure requires that your web browser can connect to the Internet, but 802.1X needs to be done before you have an IP address.

krisztian-andre commented 5 years ago

Possibly not, although MS has a working solution for this using their NPS server and an MFA extension for it.

Anyhow I am curently testing without MFA and I get the response: chris@ITAI-579-auth-vm:~$ radtest test.user@BLANKED.com BLANKED localhost 0 testing123 IGNORED 127.0.0.1 Sent Access-Request Id 251 from 0.0.0.0:34430 to 127.0.0.1:1812 length 100 User-Name = "test.user@BLANKED.com" User-Password = "BLANKED" NAS-IP-Address = 127.0.0.1 NAS-Port = 0 Message-Authenticator = 0x00 Framed-Protocol = PPP Cleartext-Password = "BLANKED" Received Access-Reject Id 251 from 127.0.0.1:1812 to 0.0.0.0:0 length 245 Reply-Message = "Error: invalid_request" Reply-Message = "AADSTS901002: The 'resource' request parameter is not supported." Reply-Message = "Trace ID: BLANKED" Reply-Message = "Correlation ID: BLANKED" Reply-Message = "Timestamp: 2019-10-06 08:31:45Z" (0) -: Expected Access-Accept got Access-Reject

What is the resource request parameter reffering to?

jimdigriz commented 5 years ago

@krisztian-andre Can you apply https://github.com/jimdigriz/freeradius-oauth2-perl/pull/6 and let me know if this resolves the problem for you.

krisztian-andre commented 5 years ago

Yes, one second. I will attach the radius log here in the meanwhile (before #6 that is). http://paste.ubuntu.com/p/zrs97SPspt/

krisztian-andre commented 5 years ago

Still getting Reply-Message = "AADSTS901002: The 'resource' request parameter is not supported."

krisztian-andre commented 5 years ago

FYI I had to change the module to filename in /etc/freeradius/3.0/mods-enabled/oauth2-perl to be able to start freeradius:

perl oauth2-perl { filename = /opt/freeradius-oauth2-perl/main.pm }

krisztian-andre commented 5 years ago

the dicovery address was pointing to a V2 endpoint which does not have a resource parameter...

Pointing it to the V1 endpoint I get "message": "Insufficient privileges to complete the operation.",\r

I suspect thiss is an issue with mz Ayure App configuration.

krisztian-andre commented 5 years ago

Looking at the logs the call that fails with

rlm_perl: "message": "Insufficient privileges to complete the operation.",\r

is

rlm_perl: GET https://graph.microsoft.com/v1.0/users?$top=999&$filter=accountEnabled+eq+true

I tested this with the graph explorer (https://developer.microsoft.com/en-us/graph/graph-explorer#) and the problem is somehow the filter parameter because

this executes fine https://graph.microsoft.com/v1.0/users?$top=999

This could be a result of an (undocumented) limitation of the /users endpoint: https://docs.microsoft.com/en-us/graph/api/user-list?view=graph-rest-1.0&tabs=http

https://docs.microsoft.com/de-de/graph/query-parameters#filter-parameter: " it is important to note that query parameters specified in a request might fail silently. This can be true for unsupported query parameters as well as for unsupported combinations of query parameters."

glauco76 commented 5 years ago

AFAIK you can't use an Azure MFA account through RADIUS only.

Microsoft provides the Azure MFA server for doing this, but MFA server requires a local AD to work, it does not work with Azure AD only, which is a pain in the x if you don't have an on premise microsoft domain (as is my case). MFA server (as many other 2FA radius servers do) will act as a radius server and ask you for a password that includes the verification code.

To bypass the MFA server and obtain the same behaviour you would have to re-implement the entire MFA request process, which is not an easy task to be done...

krisztian-andre commented 5 years ago

@glauco76 I understand, but I'd like to proceeed step by step nevertheless.

Currently I am at the point where I'm simply trying to make it work without MFA.

salihzett commented 4 years ago

It should be possible to create a conditional access for using MFA and execute this enterprise application in azure. This would bypass MFA. I found this repo for a few minutes ago and will put this on my todo list. If this is working, it would be awesome because I don’t want a separate ldap server.

salihzett commented 4 years ago

I do not think this will work as the MFA support with Azure requires that your web browser can connect to the Internet, but 802.1X needs to be done before you have an IP address.

Checking credentials needs also a valid internet connection so how should this work then?

jimdigriz commented 4 years ago

I do not think this will work as the MFA support with Azure requires that your web browser can connect to the Internet, but 802.1X needs to be done before you have an IP address.

Checking credentials needs also a valid internet connection so how should this work then?

There is a possibility of using a device flow but that is really is getting into the realms of product development.

Though I am interested in doing a "non-awful RADIUS solution" for the SME sector, it is a hard space to break into and not really convincing (to me) the juice would be worth the squeeze?

udochrist commented 4 years ago

Does someone have this working with the latest freeradius 3.0 and the current Azure AD? I fiddled with the configs and applied #6 patches. ATM i'm getting

rlm_perl: X-Ms-Ags-Diagnostic: {"ServerInfo":{"DataCenter":"West Europe","Slice":"SliceC","Ring":"5","ScaleUnit":"005","RoleInstance":"AGSFE_IN_22"}}
rlm_perl: 
rlm_perl: {\r
rlm_perl:   "error": {\r
rlm_perl:     "code": "Authorization_RequestDenied",\r
rlm_perl:     "message": "Insufficient privileges to complete the operation.",\r
rlm_perl:     "innerError": {\r
rlm_perl:       "date": "2020-06-13T16:38:55",\r
rlm_perl:       "request-id": "7bfd2f48-27c4-4d50-8489-b8982dd53a03"\r
rlm_perl:     }\r
rlm_perl:   }\r
rlm_perl: }
udochrist commented 4 years ago

Does someone have this working with the latest freeradius 3.0 and the current Azure AD? I fiddled with the configs and applied #6 patches. ATM i'm getting

rlm_perl: X-Ms-Ags-Diagnostic: {"ServerInfo":{"DataCenter":"West Europe","Slice":"SliceC","Ring":"5","ScaleUnit":"005","RoleInstance":"AGSFE_IN_22"}}
rlm_perl: 
rlm_perl: {\r
rlm_perl:   "error": {\r
rlm_perl:     "code": "Authorization_RequestDenied",\r
rlm_perl:     "message": "Insufficient privileges to complete the operation.",\r
rlm_perl:     "innerError": {\r
rlm_perl:       "date": "2020-06-13T16:38:55",\r
rlm_perl:       "request-id": "7bfd2f48-27c4-4d50-8489-b8982dd53a03"\r
rlm_perl:     }\r
rlm_perl:   }\r
rlm_perl: }

I take that back. it is working when i connect from a wifi -> Radius -> Azure. It's only the radtest that produced the exceptions. Damn.

jimdigriz commented 4 years ago

I'll look into updating and fixing up this over the next week for you.

salihzett commented 4 years ago

There is a possibility of using a device flow but that is really is getting into the realms of product development.

i didnt mean credentials for a device, i meant the access point with wifi controller needs also to check the credentials from AzureAD, so from CLIENT to WIFI to RADIUS to AzureAD it needs a connection ,isnt it?

jimdigriz commented 4 years ago

There is a possibility of using a device flow but that is really is getting into the realms of product development.

i didnt mean credentials for a device, i meant the access point with wifi controller needs also to check the credentials from AzureAD, so from CLIENT to WIFI to RADIUS to AzureAD it needs a connection ,isnt it?

...the device flow handles this.

The following does a not bad explanation of the moving parts:

https://developers.google.com/identity/protocols/oauth2/limited-input-device

jimdigriz commented 4 years ago

I'll look into updating and fixing up this over the next week for you.

@udochrist this is now done, complete rewrite in master. Let me know how you get along.

Works For Me(tm)

jimdigriz commented 4 years ago

@glauco76 I think the JSON parsing may be fixed by me just moving to use JSON::PP (pure perl without C bindings); a former work colleague of mine did this I think for the same reason.

The rewrite I just pushed yesterday should not have this problem, and it would be great to get some feedback on it from you.

jimdigriz commented 4 years ago

Closing as JSON::PP likely fixed the issue.