lemur icon indicating copy to clipboard operation
lemur copied to clipboard

Implementing SSO fails: "Exception on /api/1/auth/ping [POST]"

Open ghost opened this issue 6 years ago • 1 comments

Hi,

I'm trying to implement SSO into my instance of Lemur. I updated the scope in /www/lemur/lemur/auth/views.py to only pertain to those which we will be using (openid, email, and profile). I've also updated the configuration file lemur.conf.py to include the following:

ACTIVE_PROVIDERS = ["ping"]
PING_SECRET = 'abcdefghijklmn12345678'
PING_ACCESS_TOKEN_URL = "https://myprovider.example.com/as/token.oauth2"
PING_USER_API_URL = "https://myprovider.example.com/idp/userinfo.openid"
PING_JWKS_URL = "https://myprovider.example.com/pf/JWKS"
PING_NAME = "SSO Provider"
PING_CLIENT_ID = "lemur"
PING_REDIRECT_URI = "http://localhost/api/1/auth/ping"
PING_AUTH_ENDPOINT = "https://myprovider.example.com/as/authorization.oauth2"

This creates a button on my login page that opens a new window pertaining to my SSO provider. The SSO provider's domain is internal to our company. After signing in through SSO successfully, the pop-up window closes, but I get a red pop-up on the parent window saying "Whoa there Internal Server Error" I also do not get logged into the Lemur service (nor is a new user added to the database). The parent window still sits on the login page, unauthenticated.

The logs show that an exception had been thrown:

[2018-09-13 14:09:29,796] ERROR in app: Exception on /api/1/auth/ping [POST]
Traceback (most recent call last):
  File "/www/lemur/lib/python3.6/site-packages/urllib3/connection.py", line 171, in _new_conn
    (self._dns_host, self.port), self.timeout, **extra_kw)
  File "/www/lemur/lib/python3.6/site-packages/urllib3/util/connection.py", line 59, in create_connection
    for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM):
  File "/usr/lib/python3.6/socket.py", line 745, in getaddrinfo
    for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
socket.gaierror: [Errno -2] Name or service not known

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/www/lemur/lib/python3.6/site-packages/urllib3/connectionpool.py", line 600, in urlopen
    chunked=chunked)
  File "/www/lemur/lib/python3.6/site-packages/urllib3/connectionpool.py", line 343, in _make_request
    self._validate_conn(conn)
  File "/www/lemur/lib/python3.6/site-packages/urllib3/connectionpool.py", line 849, in _validate_conn
    conn.connect()
  File "/www/lemur/lib/python3.6/site-packages/urllib3/connection.py", line 314, in connect
    conn = self._new_conn()
  File "/www/lemur/lib/python3.6/site-packages/urllib3/connection.py", line 180, in _new_conn
    self, "Failed to establish a new connection: %s" % e)
urllib3.exceptions.NewConnectionError: <urllib3.connection.VerifiedHTTPSConnection object at 0x7fc15ed415f8>: Failed to establish a new connection: [Errno -2] Name or service not known

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/www/lemur/lib/python3.6/site-packages/requests/adapters.py", line 445, in send
    timeout=timeout
  File "/www/lemur/lib/python3.6/site-packages/urllib3/connectionpool.py", line 638, in urlopen
    _stacktrace=sys.exc_info()[2])
  File "/www/lemur/lib/python3.6/site-packages/urllib3/util/retry.py", line 398, in increment
    raise MaxRetryError(_pool, url, error or ResponseError(cause))
urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='myprovider.example.com', port=443): Max retries exceeded with url: /as/token.oauth2?grant_type=authorization_code&scope=openid+email+profile&code=abcdef123-ghijklm456&redirect_uri=http%3A%2F%2Flocalhost%2Fapi%2F1%2Fauth%2Fping&client_id=lemur (Caused by NewConnectionError('<urllib3.connection.VerifiedHTTPSConnection object at 0x7fc15ed415f8>: Failed to establish a new connection: [Errno -2] Name or service not known',))

After a bit of debugging, I found that the exception stems from /www/lemur/lemur/auth/views.py at the line r = requests.post(access_token_url, headers=headers, params=params, verify=verify_cert) within the exchange_for_access_token() function.

I printed out the value of access_token_url, which was https://myprovider.example.com/as/token.oauth2. Some Googling informed me that socket.gaierror: [Errno -2] Name or service not known may stem from the fact that it was expecting a hostname rather than a URL, ie just myprovider.example.com/as/token.oauth2 (without the https://). However, my provider requires https:// in front, otherwise I'll receive a "Could not receive response" message from the browser. Even appending port 443 as myprovider.example.com:443/as/token.oauth2 will not work. http://myprovider.example.com does not redirect to https, either. (Parsing out the https:// so access_token_url = 'myprovider.example.com/as/token.oauth2' gave me an "Invalid URL" error in the Lemur logs.)

Is there a workaround I could use to get my SSO integration working? Or, more significantly, are there any obvious issues in my implementation?

Thanks!

ghost avatar Sep 13 '18 19:09 ghost

Hi @goodvibes67 , your configuration looks very similar to our own, except that your PING_REDIRECT_URI is pointing to localhost port 80. Are you sure the local Flask service is running on port 80?

castrapel avatar Sep 24 '18 15:09 castrapel