Commit b3b34327 authored by Robin Sonnabend's avatar Robin Sonnabend

Implement Shibboleth client authentication

parents
#!/usr/bin/env python3
import re
import urllib
import html
import requests
ACTION_PATTERN = r'<form action="(?P<url>[^"]+)" method="post">'
FIELD_PATTERN = r'<input type="hidden" name="(?P<name>[^"]+)" value="(?P<value>[^"]+)"/>'
def authenticate(shib_url, username, password, verify_tls=True):
session = requests.Session()
session.verify = verify_tls
sso_response = session.get(shib_url)
sso_url = sso_response.url
if urllib.parse.urlsplit(sso_url).netloc == urllib.parse.urlsplit(shib_url).netloc:
raise ValueError("Missing redirect to SSO. Wrong login URL specified")
login_data = {
"j_username": username,
"j_password": password,
"_eventId_proceed": "",
}
login_response = session.post(sso_url, data=login_data)
if "The credentials you entered are incorrect." in login_response.text:
raise ValueError("Invalid credentials. Login failed.")
action_match = re.search(ACTION_PATTERN, login_response.text)
if not action_match:
raise ValueError("Cannot parse login response.")
shib_url = html.unescape(action_match.group("url"))
params = {}
for match in re.findall(FIELD_PATTERN, login_response.text):
name, value = match
params[name] = html.unescape(value)
shib_response = session.post(shib_url, data=params)
return session
def main():
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("url", help="URL of Shibboleth Service Provider "
"e.g. https://moodle.rwth-aachen.de/auth/shibboleth/index.php")
parser.add_argument("--username", help="Username to login with")
parser.add_argument("--password", help="Password to login with")
parser.add_argument("--no-verify", dest="verify_tls", action="store_false",
help="Do not verify TLS certificates.")
arguments = parser.parse_args()
username = arguments.username
password = arguments.password
if username is None:
username = input("Username: ")
if password is None:
import getpass
password = getpass.getpass("Password: ")
session = authenticate(arguments.url, username, password,
verify_tls=arguments.verify_tls)
print("Success!")
if __name__ == "__main__":
main()
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment