Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add SciTokens authorization #75

Closed
wants to merge 8 commits into from

Conversation

duncan-brown
Copy link
Contributor

@duncan-brown duncan-brown commented Nov 12, 2020

This pull requests adds authorization using SciTokens to the SegDB WSGI server. The SciToken should be passed in the https authorization header as

Authorization: Bearer serialized_token_text

where serialized_token_text is a serialized SciToken generated by a the issuer specified in scitokens_issuer in Constants.py. The SegDB server and the SciToken issuer need to agree on the audience for tokens, which is specified in scitokens_audience in Constants.py.

GET access to obtain segments is given to SegDB if the token scope is read:/DQSegDB and PUT and PATCH access to insert and update segments is given if the token scope is write:/DQSegDB.

If the request does not contain a valid SciToken, or the token cannot be deserialized for the right audience, the server will silently fail over to trying X509 authentication. If a SciToken is provided with the correct audience, the server will fail if the token does not contain the correct scope for the requested action and will not fall through to X509 authentication.

One this patch is merged, the SciTokens library must be installed on the server with yum -y install python2-scitokens. This has been added to the install scripts.

WSGI must to be configured to pass the authorization headers to the python layer with WSGIPassAuthorization On in wsgi.conf. See https://modwsgi.readthedocs.io/en/develop/configuration-directives/WSGIPassAuthorization.html for details. I think I did this correctly in the cit_install_script.sh and install_script.sh files, but in cit_install_script_sl7update.sh the file wsgi.conf seems to be coming from some cached location, so that file may need to be fixed separately.

In addition, the following configuration values need to be set to their production settings before deployment:

scitokens_issuer = 'https://test.cilogon.org'
scitokens_audience = 'segments.ligo.org'

The scitokens_issuer should be the URL of the scitokens issuer against which scitokens should be validated. The scitokens_audience should be the audience that is agreed for the SegDB server(s).

This patch hard codes the scitoken scopes as read:/DQSegSB for GET access to the segment database and write:/DQSegSB for PUT/PATCH access to the segment database. These scopes need to be agreed collaboration-wide. It might also make sense to make them configuration variables as well, rather than being hard coded.

Scitokens caches keys in a cache directory which is set in the configuration file to

scitokens_cache_dir = '/var/cache/httpd'

This directory should exist and have read/write by the DQSegDB server process, or should be changed to another suitable location.

@coveralls
Copy link

coveralls commented Nov 12, 2020

Coverage Status

Coverage decreased (-0.4%) to 17.424% when pulling f5ef25a on duncan-brown:scitokens into e829e29 on ligovirgo:master.

if token_data:
token_enforcer = scitokens.Enforcer(tok['iss'], audience=aud)
if token_enforcer.test(token, authz, path) is False:
raise ValueError('SciToken does not have read:/DQSegDB scope')
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to generate error message based on passed scope

@codecov-commenter
Copy link

codecov-commenter commented Jun 30, 2021

Codecov Report

Merging #75 (dd29042) into master (738718f) will decrease coverage by 0.28%.
The diff coverage is 4.08%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master      #75      +/-   ##
==========================================
- Coverage   11.99%   11.70%   -0.29%     
==========================================
  Files           5        5              
  Lines        1017     1059      +42     
==========================================
+ Hits          122      124       +2     
- Misses        895      935      +40     
Flag Coverage Δ
Linux 11.70% <4.08%> (-0.29%) ⬇️
macOS 11.70% <4.08%> (-0.29%) ⬇️
python2.7 11.70% <4.08%> (-0.29%) ⬇️
python3.5 ?
python3.6 ?
python3.7 ?
python3.8 ?
python3.9 ?

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
dqsegdb/urifunctions.py 13.63% <4.08%> (-3.33%) ⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 738718f...dd29042. Read the comment docs.

def __init__(self):
self.admin = Admin.AdminHandle()
self.constant = Constants.ConstantsHandle()
os.environ['XDG_CACHE_HOME'] = self.constant.scitokens_cache_dir
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this needed?

Comment on lines +234 to +236
r = [200]
# Otherwise, using HTTPS.
else:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this just return [200] then we can drop the else and deindent the rest of this (very long) function.

Suggested change
r = [200]
# Otherwise, using HTTPS.
else:
return [200]
# Otherwise, using HTTPS.

Comment on lines +258 to +259
r = self.admin.log_and_set_http_code(401, c, req_method, "SciToken signature has expired", full_uri)
return r
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
r = self.admin.log_and_set_http_code(401, c, req_method, "SciToken signature has expired", full_uri)
return r
return self.admin.log_and_set_http_code(401, c, req_method, "SciToken signature has expired", full_uri)

Comment on lines +255 to +256
r = self.admin.log_and_set_http_code(401, c, req_method, "Invalid audience for SciToken", full_uri)
return r
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
r = self.admin.log_and_set_http_code(401, c, req_method, "Invalid audience for SciToken", full_uri)
return r
return self.admin.log_and_set_http_code(401, c, req_method, "Invalid audience for SciToken", full_uri)

res = ldbdwauth.check_authorization_gridmap(environ, environ['REQUEST_METHOD'], environ['REQUEST_URI'], False)
try:
res = ldbdsauth.check_authorization_scitoken(environ, environ['REQUEST_METHOD'], environ['REQUEST_URI'], False)
except:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please don't use empty except, I presume this should only protect against KeyError which indicates that no token was given

Suggested change
except:
except KeyError:

res = ldbdwauth.check_authorization_gridmap(environ, environ['REQUEST_METHOD'], environ['REQUEST_URI'], True)
try:
res = ldbdsauth.check_authorization_scitoken(environ, environ['REQUEST_METHOD'], environ['REQUEST_URI'], True)
except:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as above

Suggested change
except:
except KeyError:

@robertbruntz
Copy link
Contributor

@duncan-brown - For anyone who wasn't in this meeting and institutional memory, could you list the elements that need to be modified before we could deploy this?

@duncanmmacleod duncanmmacleod marked this pull request as draft July 1, 2021 14:49
@duncan-brown
Copy link
Contributor Author

@robertbruntz I updated the main text in the pull request with the items that need to be configured. It might also be a good idea to make the scopes a configurable option in the ini file, rather than hard coded, so I noted that as well.

@robertbruntz
Copy link
Contributor

This PR was split into 2 MRs on LIGO GitLab:

All additional work and comments should be in those repos.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants