OpenIDC / mod_auth_openidc

OpenID Certified™ OpenID Connect Relying Party implementation for Apache HTTP Server 2.x
Apache License 2.0
990 stars 327 forks source link

Add option to validate domain from email #136

Closed pietercvdm closed 8 years ago

pietercvdm commented 8 years ago

I've setup Apache as a OAuth2 Resource server as described in the wiki to protect an API using OAuth2.

Google doesn't seem to return the hd parameter even though it is specified in the authorisation request URL (https://accounts.google.com/o/oauth2/auth?client_id=xx&response_type=code&redirect_uri=abc&scope=abc&login_hint=aaa@example.com&access_type=offline&hd=example.com&approval_prompt=force).

The claims returned are:

{
  "issued_to": "xxxxx-14o88438e8gvfmeup0bge5f4hi272o99.apps.googleusercontent.com",
  "audience": "xxxxxx-14o88438e8gvfmeup0bge5f4hi272o99.apps.googleusercontent.com",
  "user_id": "xxxxx14665377302725",
  "scope": "https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/script.external_request https://www.googleapis.com/auth/script.scriptapp https://www.googleapis.com/auth/plus.me",
  "expires_in": 3588,
  "email": "aaa@example.com",
  "verified_email": true,
  "access_type": "offline"
}

Doing a bit of Googling I get mixed results with some saying that the hd parameter may not be well supported by newer versions of Google's OAuth implementation but some documentation saying it should work. It doesn't seem to be working.

I don't have an effective way in Apache to limit access using the domain.

Is there another way to maybe write the "Require claim ..." directive to check for the domain? Looking through the source it seems like an = match.

Would it be possible to add support in some way to test the domain returned by the email address using your plugin? Something like "Require claim email:@example.com" which would then test that the email ends in example.com.

zandbelt commented 8 years ago

That would be possible using regular expression matching, something like Require claim "email~^(.*)@example.com$" (untested) as documented in https://github.com/pingidentity/mod_auth_openidc/wiki/Authorization#1-mod_auth_openidc

let me know if that works for you

pietercvdm commented 8 years ago

Works like a charm. I should have seen that! Thanks for the quick response.

zandbelt commented 8 years ago

there's one caveat with this: anyone could register any e-mail address with their Google account; you will need to make sure that e-mail validation for your domain ("example.com") is controlled by you, "verified_email" is true, and that all users that can read e-mail on an account in "example.com" are allowed to have access to your Apache protected resources

pietercvdm commented 8 years ago

Thanks for the info. I've added to also check for verified_email:true and we are the only people who can create (and therefore I assume 'verify') users in our domain with Google.

zandbelt commented 8 years ago

remember there's no easy way to do this in Apache config only: specifying multiple "Require claim:" directives are combined as a logical "OR", not an "AND"; how did you solve this?

pietercvdm commented 8 years ago

We're running Apache > 2.4 so I used the container directive.

<RequireAll>
    Require claim email~^(.*)@example.com$
    Require claim verified_email:true
</RequireAll>

I tested it with a few scenarios and it seems to correctly combine the Require statement with an "AND".

Edit: The RequireAll container directive seems to be available since Apache 2.3.

zandbelt commented 8 years ago

very good! thanks