oxyno-zeta / s3-proxy

S3 Reverse Proxy with GET, PUT and DELETE methods and authentication (OpenID Connect and Basic Auth)
https://oxyno-zeta.github.io/s3-proxy/
Apache License 2.0
309 stars 34 forks source link

does this support Azure active directory for authentication and authorization ? #418

Closed skokasik closed 10 months ago

skokasik commented 10 months ago

Hi There,

sorry to open a bug, I just want to ask further question about integration the authentication and authorization with Azure AD.

I can't seem to get the authentication and authorization working with azure AD , any good example on the configuration ?

Thank you in advance,

-Sep

oxyno-zeta commented 10 months ago

Hello @skokasik ,

Azure AD is clearly not supported directly in the app, I'm sorry.

You can succeed in doing this using an authentication proxy before S3-Proxy by using a sidecar in the helm chart or with your infrastructure directly.

It seems doable with combo Oauth2-Proxy (CF : https://oauth2-proxy.github.io/oauth2-proxy/docs/configuration/oauth_provider#microsoft-azure-ad-provider ) and this part of the configuration: https://oxyno-zeta.github.io/s3-proxy/configuration/structure/#headerauthconfiguration

But I don't have an example, sorry. If you have one, I will be happy to save it in the documentation.

Tell me if this isn't clear.

Oxyno-zeta

skokasik commented 10 months ago

hi @oxyno-zeta , Thank you for your quick response. really appreciated it. It's great to get confirmation that azure AD isn't supported.

I was changing the configuration to match what is required from azure AD oauth2. for some reason, I managed to get authentication challenge from Azure AD by using the following configuration when hitting my development site and it seems to be working aside from the authorization:

oidc:
     provider1:
       clientID: 1assdfs- redacted
       clientSecret:
         value: Qsdfsd-sdfsdfs- redacted
       state: state-key
       issuerUrl: https://login.microsoftonline.com/<tenant id>/v2.0
       redirectUrl: <base url>
       Scopes:
        - openid # change oidc to openid
        - email
        - profile
       groupClaim: groups 
       cookieSecure: false 
       cookieName: oidc 
       emailVerified: false
       loginPath: /auth 
       callbackPath: /callback 

first-bucket:
    mount:
      path:
        - /
    resources:
       - path: /*
         # Whitelist
         provider: provider1
         methods:
          - GET
         oidc:
           authorizationAccesses: [] # Authorization accesses : groups or email or regexp

I'll checkout the oauth2-proxy , thanks again for pointing me to the right direction. Would you happen to know whether authorization against Azure AD groups can be supported if using oauth2-proxy ? e.g. only allow access to specific path for those who have a claim with specific ad group. I believe oauth2-proxy is only for authentication.

Cheers,

sk

oxyno-zeta commented 10 months ago

Hello @skokasik ,

I didn't know Azure AD was capable of doing the OIDC protocol. If it can, then your configuration should work.

In the other possibility , Oauth2-Proxy can forward groups in a header if I'm correct.

Do not hesitate!

skokasik commented 10 months ago

Thanks @oxyno-zeta. yep azure also support OIDC protocol.

continuining with my trial to get the authorization to work without Oauth2-Proxy.

oidc:
     provider1:
       clientID: 1assdfs- redacted
       clientSecret:
         value: Qsdfsd-sdfsdfs- redacted
       state: state-key
       issuerUrl: https://login.microsoftonline.com/<tenant id>/v2.0
       redirectUrl: <base url>
       Scopes:
        - openid # change oidc to openid
        - email
        - profile
       groupClaim: groups 
       cookieSecure: false 
       cookieName: oidc 
       emailVerified: false
       loginPath: /auth 
       callbackPath: /callback 

first-bucket:
    mount:
      path:
        - /
    resources:
       - path: /*
         # Whitelist
         provider: provider1
         methods:
          - GET
         oidc:
           authorizationAccesses: 
              - group: someAdgroup

I am getting forbidden user sk@domain.com. i made sure that I am part of someAdgroup. I assume the someAdgroup is used to match the response header which should contain the group claim for a specific user.

authorizationAccesses:

oxyno-zeta commented 10 months ago

Hello again,

In cookies, you can find your jwt token in clear. You can go to jwt.io website to check what's inside the token and see the claims (JSON key) with your groups in.

Hope you will find the good one quickly!

skokasik commented 10 months ago

Hello , thank you for the pointer. totally hit the bulleyes, the problem is the group claim isn't returned as part of the JWT token. i think it might be settings in the registration in the azure AD but also might be how the retrieval of the token is performed.

I tried to add email on the authorizationAccesses, this seems to do the trick since email field is part of the JWT token.


 resources:
       - path: /*
         # Whitelist
         provider: provider1
         methods:
          - GET
         oidc:
           authorizationAccesses: 
              - group: someAdgroup
              - email: sk@domain.com

I'll dig further on the registration on azure AD. Can I please get some direction on location in the source code where the token is requested, I would be keen to see how it's done.

ohh another question, does configuration related to authorizationAccesses is hot reloaded ? e.g. if i were to change configuration file especially the section authorizationAccesses with another source via script, would this change require the app to be restarted or can the app pick up the latest configuration file . I want to make sure that the list of AD groups or emails are in synced with another source to ensure latest filtering rule.

really appreciated your quick response!

cheers, -sk

oxyno-zeta commented 10 months ago

Hello @skokasik ,

Happy to hear that it helped you !

You have to know something: OIDC tokens do not necessarily have groups in them. This is a common "hack" to have something quickly but this isn't a standard. There are very good reasons to avoid putting groups in tokens: monstrous tokens because you have 50 groups as a user in the company and so hitting the cookie limit or header limit, leaking structural information about organisation in your company,... I often say that OIDC tokens are like passports, they say who you are but it will never say you are a tennis player for example. That's why email is supported in s3-proxy. This is a sure field.

If you want to see the code, you can check in "pkg/s3-proxy/authx".

For your last question: yes it is hot reloaded !! Only a few fields aren't (server ports and that's all if I'm remembering well). As an OPS, restarting apps to change a config is.... You see my point ;)

Tell me if something isn't clear

skokasik commented 10 months ago

Hi @oxyno-zeta , Totally agree with the groups limit which may cause issue! Fortunately recently maybe few years ago Microsoft added option to only include Group assigned to the application thus removing potential issue where one person is assigned to like 50 - 200 groups. This means it will ignore all other groups that are not registered to your application which is great!

"pkg/s3-proxy/authx" -> i'll check this out.

i managed to get it working by changing the token configuration and configure to send back the group claim but only groups assigned to the application.


resources:
      - path: /*
        # Whitelist
        provider: provider1
        methods:
         - GET
        oidc:
          authorizationAccesses: 
             - group: someAdgroup

just have to ensure that someAdgroup is registered to a specific application during application registration on azure AD. Add groups claim to the token generated and token id configuration is set to return sAMAcountName. The default is Group Id which will return guid in jwt.

if using guid i would think "someAdgroup" in the configuration will have to change to a guid.

For your last question: yes it is hot reloaded !! Only a few fields aren't (server ports and that's all if I'm remembering well). As an OPS, restarting apps to change a config is.... You see my point ;)

Awesome! this is music to my ears. thank again @oxyno-zeta

please feel free to close the question :) much appreciated the work and the response! I'll raise another question if i still have further question.

hope 2024 has been great for you so far. happy new year!

cheers,

-sk

oxyno-zeta commented 10 months ago

Hello @skokasik ,

i managed to get it working by changing the token configuration and configure to send back the group claim but only groups assigned to the application.

Very cool ! I didn't know this was possible.

if using guid i would think "someAdgroup" in the configuration will have to change to a guid.

I can understand why you want to use the sAMAcountName instead of guid. This isn't very simple to use...

Awesome! this is music to my ears.

Ahah. I'm glad to ear this and very amused :) .

much appreciated the work and the response! I'll raise another question if i still have further question.

You are welcome ! Do not hesitate. I'm always trying to help when I can.

Happy new year too !

Oxyno-zeta