mirror of
https://github.com/cwinfo/powerdns-admin.git
synced 2024-12-30 15:05:39 +00:00
Azure OAuth - add Group mappings to Roles
This commit is contained in:
parent
3bf6e6e9f1
commit
765eab999a
@ -73,6 +73,10 @@ class Setting(db.Model):
|
|||||||
'https://login.microsoftonline.com/[tenancy]/oauth2/v2.0/token',
|
'https://login.microsoftonline.com/[tenancy]/oauth2/v2.0/token',
|
||||||
'azure_oauth_authorize_url':
|
'azure_oauth_authorize_url':
|
||||||
'https://login.microsoftonline.com/[tenancy]/oauth2/v2.0/authorize',
|
'https://login.microsoftonline.com/[tenancy]/oauth2/v2.0/authorize',
|
||||||
|
'azure_sg_enabled': False,
|
||||||
|
'azure_admin_group': '',
|
||||||
|
'azure_operator_group': '',
|
||||||
|
'azure_user_group': '',
|
||||||
'oidc_oauth_enabled': False,
|
'oidc_oauth_enabled': False,
|
||||||
'oidc_oauth_key': '',
|
'oidc_oauth_key': '',
|
||||||
'oidc_oauth_secret': '',
|
'oidc_oauth_secret': '',
|
||||||
|
@ -720,6 +720,10 @@ def setting_authentication():
|
|||||||
request.form.get('azure_oauth_token_url'))
|
request.form.get('azure_oauth_token_url'))
|
||||||
Setting().set('azure_oauth_authorize_url',
|
Setting().set('azure_oauth_authorize_url',
|
||||||
request.form.get('azure_oauth_authorize_url'))
|
request.form.get('azure_oauth_authorize_url'))
|
||||||
|
Setting().set('azure_sg_enabled', True if request.form.get('azure_sg_enabled')=='ON' else False)
|
||||||
|
Setting().set('azure_admin_group', request.form.get('azure_admin_group'))
|
||||||
|
Setting().set('azure_operator_group', request.form.get('azure_operator_group'))
|
||||||
|
Setting().set('azure_user_group', request.form.get('azure_user_group'))
|
||||||
result = {
|
result = {
|
||||||
'status': True,
|
'status': True,
|
||||||
'msg': 'Saved successfully. Please reload PDA to take effect.'
|
'msg': 'Saved successfully. Please reload PDA to take effect.'
|
||||||
|
@ -201,7 +201,19 @@ def login():
|
|||||||
return redirect(url_for('index.index'))
|
return redirect(url_for('index.index'))
|
||||||
|
|
||||||
if 'azure_token' in session:
|
if 'azure_token' in session:
|
||||||
me = json.loads(azure.get('me').text)
|
azure_info = azure.get('me?$select=displayName,givenName,id,mail,surname,userPrincipalName,preferredName,memberOf').text
|
||||||
|
current_app.logger.info('Azure loginreturned: '+azure_info)
|
||||||
|
me = json.loads(azure_info)
|
||||||
|
|
||||||
|
azure_info = azure.post('me/getMemberGroups',json={'securityEnabledOnly': False}).text
|
||||||
|
current_app.logger.info('Azure groups returned: '+azure_info)
|
||||||
|
grouplookup = json.loads(azure_info)
|
||||||
|
# Groups are in mygroups['value'] which is an array
|
||||||
|
if "value" in grouplookup:
|
||||||
|
mygroups = grouplookup["value"]
|
||||||
|
else:
|
||||||
|
mygroups = []
|
||||||
|
|
||||||
azure_username = me["userPrincipalName"]
|
azure_username = me["userPrincipalName"]
|
||||||
azure_givenname = me["givenName"]
|
azure_givenname = me["givenName"]
|
||||||
azure_familyname = me["surname"]
|
azure_familyname = me["surname"]
|
||||||
@ -211,6 +223,7 @@ def login():
|
|||||||
azure_email = ""
|
azure_email = ""
|
||||||
if not azure_email:
|
if not azure_email:
|
||||||
azure_email = me["userPrincipalName"]
|
azure_email = me["userPrincipalName"]
|
||||||
|
|
||||||
# Handle foreign principals such as guest users
|
# Handle foreign principals such as guest users
|
||||||
azure_email = re.sub(r"#.*$", "", azure_email)
|
azure_email = re.sub(r"#.*$", "", azure_email)
|
||||||
azure_username = re.sub(r"#.*$", "", azure_username)
|
azure_username = re.sub(r"#.*$", "", azure_username)
|
||||||
@ -235,6 +248,25 @@ def login():
|
|||||||
|
|
||||||
session['user_id'] = user.id
|
session['user_id'] = user.id
|
||||||
session['authentication_type'] = 'OAuth'
|
session['authentication_type'] = 'OAuth'
|
||||||
|
|
||||||
|
# Handle group memberships, if defined
|
||||||
|
if Setting().get('azure_sg_enabled'):
|
||||||
|
if Setting().get('azure_admin_group') in mygroups:
|
||||||
|
current_app.logger.info('Setting role for user '+azure_username+' to Administrator due to group membership')
|
||||||
|
user.set_role("Administrator")
|
||||||
|
else:
|
||||||
|
if Setting().get('azure_operator_group') in mygroups:
|
||||||
|
current_app.logger.info('Setting role for user '+azure_username+' to Operator due to group membership')
|
||||||
|
user.set_role("Operator")
|
||||||
|
else:
|
||||||
|
if Setting().get('azure_user_group') in mygroups:
|
||||||
|
current_app.logger.info('Setting role for user '+azure_username+' to User due to group membership')
|
||||||
|
user.set_role("User")
|
||||||
|
else:
|
||||||
|
current_app.logger.warning('User '+azure_username+' has no relevant group memberships')
|
||||||
|
session.pop('azure_token', None)
|
||||||
|
return render_template('login.html', saml_enabled=SAML_ENABLED, error=('User '+azure_username+' is not in any authorised groups.'))
|
||||||
|
|
||||||
login_user(user, remember=False)
|
login_user(user, remember=False)
|
||||||
signin_history(user.username, 'Azure OAuth', True)
|
signin_history(user.username, 'Azure OAuth', True)
|
||||||
return redirect(url_for('index.index'))
|
return redirect(url_for('index.index'))
|
||||||
|
@ -384,7 +384,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>ADVANCE</legend>
|
<legend>ADVANCED</legend>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="azure_oauth_scope">Scope</label>
|
<label for="azure_oauth_scope">Scope</label>
|
||||||
<input type="text" class="form-control" name="azure_oauth_scope" id="azure_oauth_scope" placeholder="e.g. email" data-error="Please input scope - e.g. User.Read" value="{{ SETTING.get('azure_oauth_scope') }}">
|
<input type="text" class="form-control" name="azure_oauth_scope" id="azure_oauth_scope" placeholder="e.g. email" data-error="Please input scope - e.g. User.Read" value="{{ SETTING.get('azure_oauth_scope') }}">
|
||||||
@ -406,6 +406,36 @@
|
|||||||
<span class="help-block with-errors"></span>
|
<span class="help-block with-errors"></span>
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
<fieldset>
|
||||||
|
<legend>GROUP SECURITY</legend>
|
||||||
|
<div class="form-group">
|
||||||
|
<label>Status</label>
|
||||||
|
<div class="radio">
|
||||||
|
<label>
|
||||||
|
<input type="radio" name="azure_sg_enabled" id="azure_sg_off" value="OFF" {% if not SETTING.get('azure_sg_enabled') %}checked{% endif %}> OFF
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<label>
|
||||||
|
<input type="radio" name="azure_sg_enabled" id="azure_sg_on" value="ON" {% if SETTING.get('azure_sg_enabled') %}checked{% endif %}> ON
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="azure_admin_group">Admin group</label>
|
||||||
|
<input type="text" class="form-control" name="azure_admin_group" id="azure_admin_group" placeholder="e.g. 00000000-0000-0000-0000-000000000000" data-error="Please input the ID for Admin group" value="{{ SETTING.get('azure_admin_group') }}">
|
||||||
|
<span class="help-block with-errors"></span>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="azure_operator_group">Operator group</label>
|
||||||
|
<input type="text" class="form-control" name="azure_operator_group" id="azure_operator_group" placeholder="e.g. 00000000-0000-0000-0000-000000000000" data-error="Please input the ID for Operator group" value="{{ SETTING.get('azure_operator_group') }}">
|
||||||
|
<span class="help-block with-errors"></span>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="azure_user_group">User group</label>
|
||||||
|
<input type="text" class="form-control" name="azure_user_group" id="azure_user_group" placeholder="e.g. 00000000-0000-0000-0000-000000000000" data-error="Please input the ID for User group" value="{{ SETTING.get('azure_user_group') }}">
|
||||||
|
<span class="help-block with-errors"></span>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<button type="submit" class="btn btn-flat btn-primary">Save</button>
|
<button type="submit" class="btn btn-flat btn-primary">Save</button>
|
||||||
</div>
|
</div>
|
||||||
@ -414,6 +444,19 @@
|
|||||||
<div class="col-md-8">
|
<div class="col-md-8">
|
||||||
<legend>Help</legend>
|
<legend>Help</legend>
|
||||||
<p>Fill in all the fields in the left form.</p>
|
<p>Fill in all the fields in the left form.</p>
|
||||||
|
<p>You first need to define an Application Registration in your Azure Active Directory, with the appropriate HTTPS URL for this endpoint, and with the appropriate rights, as explained in the documentation.</p>
|
||||||
|
<p><ul>
|
||||||
|
<li>Under the Azure Active Directory, select App Registrations, and create a new one. Give it any name you want, and the Redirect URI shoule be type 'Web' and of the format <b>https://powerdnsadmin/azure/authorized</b> (replace the host name approriately).</li>
|
||||||
|
<li>Select the newly-created registration</li>
|
||||||
|
<li>On the Overview page, the Application ID is your new Client ID to use with PowerDNS-Admin</li>
|
||||||
|
<li>On the Overview page, make a note of your Directory/Tenant ID - you need it for the API URLs later</li>
|
||||||
|
<li>Ensure Access Tokens are enabled in the Authentication section</li>
|
||||||
|
<li>Under Certificates and Secrets, create a new Client Secret. Note this secret as it is the new Client Secret to use with PowerDNS-Admin</li>
|
||||||
|
<li>Under API Permissions, you need to add permissions. Add permissions for Graph API, Delegated. Add: email, openid, profile, GroupMember.Read, User.Read and possibly User.Read.All. You then need to grant admin approval for your organisation.</li>
|
||||||
|
<li>For the Scope, use <b>User.Read openid mail profile</b></li>
|
||||||
|
<li>Replace the [tenantID] in the default URLs for authorize and token with your Tenant ID.</li>
|
||||||
|
</ul></p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
Reference in New Issue
Block a user