Feedback requested on how I integrated AWS ALB (w/OIDC) into MediaCMS #700
Replies: 3 comments 1 reply
-
Beta Was this translation helpful? Give feedback.
-
Hey @alfred-stokespace , will try to have a detailed look and see if I can contribute anything useful. And thanks for your good words and for this work! It would be great if you can share a few words on what scenario you're working on. Cheers |
Beta Was this translation helpful? Give feedback.
-
I found a problem with this approach recently. And I suspect this issue will hit anyone else that tries to connect any identity authority to MediaCMS in an SSO implementation. When you populate username in MediaCMS you have to be careful to respect the "only letters and numbers" requirement. My identity provider (and our administration rules on usernames) allow for things like This meant that a user logging in would get a user created in the db but would then get a 500 during page loading while trying to execute the edit_url reverse function.
I "fixed" this issue in my installation by adding some protection code on authentication that converts non-conformant characters to some other character. Basically, the point of all this is Media CMS doesn't support having a consistent "username" with the rest of your organization. The rest of your software systems might display/refer to your user "steve-worker" but mediaCMS has no way to support "steve-worker" and poor Steve will have to be something like "steveworker" in mediacms. |
Beta Was this translation helpful? Give feedback.
-
First off let me thank @mgogoulos and everyone else that has contributed to this project. I've found it very compelling option in this space.
Some caveats; I'm not much of a Python programmer and not terribly familiar with Django. The code I'm going to post could use polishing, especially around configurability and error handling.
I did however figure out how to get an AWS ALB w/SSL termination and OIDC support to sit in front of Mediacms and have that tie in with the user tables. Also! I preserved API support, I'll explain how that works later...
For my ALB I had AWS managing the SSL certificate, standard stuff. In my environment I used an Azure IDP and configured the ALB with valid cliend id, secret and all the endpoints and such. Then this doc from AWS helped https://docs.aws.amazon.com/elasticloadbalancing/latest/application/listener-authenticate-users.html#user-claims-encoding
The behavior for the code below is that a user that passes the auth challenges of OIDC at the ALB level is allowed to pass requests back to the MediaCMS nginx instance and along with those requests are standard headers containing JWT details. So the strategy I took was to figure out what parts of Django I had to extend in order to grab the headers, validate the jwt against AWS's public key and then pull anything I needed out of the jwt payload and populate it in the user object table that Mediacms already supports.
That part about populating the user is going to be very domain specific. For me the simple population found below is appropriate.
After first population (which has the hard validation) I just use the standard
is_authenticated
capabilities of Django and do simple confirmation that the user looks valid and then allow them to load the user object.Now via a second ALB (or direct ip) you can still log in as the admin user and do everything you would expect. You just can't expect the admin user to work through the OIDC ALB since it would have to be a legit user in your IDP (and my admin user is not).
The admin user (coming through side channel) can turn the jwt populated users into Admins! Which is nice. That way you don't need to mess with claims if you don't want to in your IDP, you can just pick users to be editors or managers or full admins and the next time they open the site through OIDC ALB they have those permissions..
Now passwords don't exist for OIDC populated users. Which is fine. I think? As for API access here is what I did....
An admin user can create tokens in the admin ui and assign those tokens to any user. So for API interaction of an OIDC populated user I'm going to (and have already tested this works!) issue manually created tokens and distribute them via our internal secrets management to the users that need API access.
... the code diff (which I based off of
6fd9a7d37f2b273b0171ab77af35dde506e2fb2e
)For anyone that is more knowledgeable about Django or Python or general authentication techniques and practices, I'd love feedback on how to make this better.
I don't think my code is going to be flexible enough to handle general cases, or at least there will be a significant amount of configuration design to handle the cases well.
Beta Was this translation helpful? Give feedback.
All reactions