simon-andrews / umass-toolkit

Tools for accessing and using data from the University of Massachusetts Amherst. Unofficial.
https://umass-toolkit.readthedocs.io/en/latest/
MIT License
11 stars 6 forks source link

NetID authentication #14

Open simon-andrews opened 6 years ago

simon-andrews commented 6 years ago

So that programs using UMTK can authenticate UMass people.

Some quick poking around points to UMass using SAML, I think? I have no idea what I'm talking about LMAO :stuck_out_tongue:

Something along the lines of:

from umass_toolkit import auth
user = auth.NetID(username="johnsmith", password="qwerty")
# and then...
do_some_super_secure_action(user=user)

or maybe something different I dunno.

MiloCS commented 6 years ago

This seems difficult to do, unless we want to use selenium to try to login to spire and verify a valid login or something like that, because we don't have access to the UMass authentication APIs (I think they use LDAP, but idk how relevant the actual behind-the-scenes authentication protocol is to us)

mattrossman commented 5 years ago

What is the intended use case for this? Is it to perform protected actions on UMass applications like SPIRE? Or for people who want to create their own applications and back it using UMass authentication?

In the latter case, if the goal just is to validate a user/password combination, the response code of a POST to webauth.umass.edu (the authentication page you get to when trying to login to Moodle) seems to discern between these cases. 200 OK for valid, 302 redirect for incorrect credentials.

For the former use case it would be nice to have a module for interfacing with SPIRE actions. I've had some luck with using requests to log into SPIRE and submit forms so I could look into this.

simon-andrews commented 5 years ago

I was thinking the latter. The best thing I'd found was an LDAP server that uses NetIDs for authentication: https://www.umass.edu/it/support/email/look-up-umass-amherst-email-addresses-thunderbird-windows.

mattrossman commented 5 years ago

You can successfully authenticate NetID credentials using the python-ldap package as follows:

import ldap

def valid_credentials(username: str, password: str) -> bool:
    ldap_server = "ldap://ldap.oit.umass.edu"
    bind_dn = 'uid=%s,ou=people,dc=umass,dc=edu' % username
    connect = ldap.initialize(ldap_server)
    connect.start_tls_s()
    try:
        connect.simple_bind_s(bind_dn, password)
        return True
    except ldap.INVALID_CREDENTIALS:
        return False

From there I'm just not sure the best way to structure things. In your original proposal there was a NetID class which gets authenticated upon initialization.

What do you think about just having a static authentication method instead of a user class? I'm not sure what the benefit of holding onto an object would be. We could return a boolean value for whether authentication is successful, or implement a more complex error system (e.g. to handle cases when there's network issues).

Simple example:

from umass_toolkit import auth

username = ''
while True:
    username = input('Enter your NetID:')
    password = input('Enter your password:')
    if auth.valid_credentials(username, password):
        break
    else:
        print('Invalid credentials. Please try again.')

print('Welcome, %s' % username)

I'm also curious if there are plans to include anything else in the auth module.