Thehive: OAuth2 User Info Failure

Created on 8 Jun 2019  路  18Comments  路  Source: TheHive-Project/TheHive

OAuth2 User Info Failure

Request Type

Bug

Work Environment

| Question | Answer
|---------------------------|--------------------
| OS version (server) | Debian
| OS version (client) | OSX
| TheHive version | 3.3.0-1
| Package Type | Docker
| Browser type & version | Firefox 67.0.1

Problem Description

We are attempting to use the OAuth2 Authentication method implemented in #430, however we are getting an authentication error after the sign-on.

Steps to Reproduce

  1. Go to login page
  2. Click 'Sign in with SSO'
  3. Authenticate with your SSO provider
  4. After authentication happens, a red box with Authentication Failure pops up, and the log message below appears in the log

Complementary information

This is the log we get when the authentication fails

thehive_1        | [error] o.e.s.a.MultiAuthSrv - Authentication failure
thehive_1        | org.elastic4play.AuthenticationError: User info fails:
thehive_1        |      at services.mappers.SimpleUserMapper.getUserFields(SimpleUserMapper.scala:40)
thehive_1        |      at services.mappers.MultiUserMapperSrv.getUserFields(MultiUserMapperSrv.scala:28)
thehive_1        |      at services.OAuth2Srv.$anonfun$getOrCreateUser$1(OAuth2Srv.scala:131)
thehive_1        |      at scala.Option.fold(Option.scala:158)
thehive_1        |      at services.OAuth2Srv.withOAuth2Config(OAuth2Srv.scala:76)
thehive_1        |      at services.OAuth2Srv.getOrCreateUser(OAuth2Srv.scala:130)
thehive_1        |      at services.OAuth2Srv.$anonfun$getAuthTokenAndAuthenticate$5(OAuth2Srv.scala:118)
thehive_1        |      at scala.concurrent.Future.$anonfun$flatMap$1(Future.scala:303)
thehive_1        |      at scala.concurrent.impl.Promise.$anonfun$transformWith$1(Promise.scala:37)
thehive_1        |      at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:60)
thehive_1        | [info] o.e.ErrorHandler - POST /api/ssoLogin?code=REDACTED_CODE returned 401
thehive_1        | org.elastic4play.AuthenticationError: Authentication failure
thehive_1        |      at org.elastic4play.services.auth.MultiAuthSrv$$anonfun$authenticate$6.applyOrElse(MultiAuthSrv.scala:75)
thehive_1        |      at org.elastic4play.services.auth.MultiAuthSrv$$anonfun$authenticate$6.applyOrElse(MultiAuthSrv.scala:71)
thehive_1        |      at scala.concurrent.Future.$anonfun$recoverWith$1(Future.scala:413)
thehive_1        |      at scala.concurrent.impl.Promise.$anonfun$transformWith$1(Promise.scala:37)
thehive_1        |      at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:60)
thehive_1        |      at akka.dispatch.BatchingExecutor$AbstractBatch.processBatch(BatchingExecutor.scala:55)
thehive_1        |      at akka.dispatch.BatchingExecutor$BlockableBatch.$anonfun$run$1(BatchingExecutor.scala:91)
thehive_1        |      at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:12)
thehive_1        |      at scala.concurrent.BlockContext$.withBlockContext(BlockContext.scala:81)
thehive_1        |      at akka.dispatch.BatchingExecutor$BlockableBatch.run(BatchingExecutor.scala:91)

Our configuration is:

...
  oauth2 {
    clientId = "the-clientid"
    clientSecret = "the-secret"
    redirectUri = "https://thehive-host/index.html#login"
    responseType = "code"
    grantType = "authorization_code"
    authorizationUrl = "https://oauth-host/oidc/authorize"
    tokenUrl = "https://oauth-host/oidc/token"
    userUrl = "https://oauth-host/oidc/userinfo"
    scope = "openid"
  }

   sso {
        mapper = simple
        autocreate = true
        defaultRoles = ["read"]
        attributes {
                login = "sub"
                name = "name"
                }
        }
...

Looking at the code here, it appears that the error should be printed in the log after "User info fails: ", however in our logs nothing is showing up there.

Any help or pointers is appreciated, thank you!

Most helpful comment

I am having the same issue. I am using a 3.4.0-RC1 Hive veversion, please find my logs below:

[error] o.e.s.a.MultiAuthSrv - **Authentication failure**
java.lang.IllegalArgumentException: Invalid URL 
at play.api.libs.ws.ahc.StandaloneAhcWSClient.validate(StandaloneAhcWSClient.scala:84)
at play.api.libs.ws.ahc.StandaloneAhcWSClient.url(StandaloneAhcWSClient.scala:42)
at play.api.libs.ws.ahc.AhcWSClient.url(AhcWSClient.scala:37)
at services.mappers.GroupUserMapper.$anonfun$getUserFields$2(GroupUserMapper.scala:43)
at scala.Option.fold(Option.scala:158)
at services.mappers.GroupUserMapper.getUserFields(GroupUserMapper.scala:43)
at services.mappers.MultiUserMapperSrv.getUserFields(MultiUserMapperSrv.scala:27)
at services.OAuth2Srv.$anonfun$getOrCreateUser$1(OAuth2Srv.scala:123)
at scala.Option.fold(Option.scala:158)
at services.OAuth2Srv.withOAuth2Config(OAuth2Srv.scala:66)
Caused by: java.lang.IllegalArgumentException:  could not be parsed into a proper Uri, missing scheme
at play.shaded.ahc.org.asynchttpclient.uri.Uri.create(Uri.java:40)
at play.shaded.ahc.org.asynchttpclient.uri.Uri.create(Uri.java:32)
at play.api.libs.ws.ahc.StandaloneAhcWSClient.validate(StandaloneAhcWSClient.scala:81)
at play.api.libs.ws.ahc.StandaloneAhcWSClient.url(StandaloneAhcWSClient.scala:42)
at play.api.libs.ws.ahc.AhcWSClient.url(AhcWSClient.scala:37)
at services.mappers.GroupUserMapper.$anonfun$getUserFields$2(GroupUserMapper.scala:43)
at scala.Option.fold(Option.scala:158)
at services.mappers.GroupUserMapper.getUserFields(GroupUserMapper.scala:43)
at services.mappers.MultiUserMapperSrv.getUserFields(MultiUserMapperSrv.scala:27)
at services.OAuth2Srv.$anonfun$getOrCreateUser$1(OAuth2Srv.scala:123)
[info] o.e.ErrorHandler - POST /api/ssoLogin?code=fc0c6142-4056-4017-9ee0-d181a1d27b86.3c566da0-3eb0-4ed2-83c4-6f942fc4462f.ecde927e-733e-4477-b0ff-93238254eaa6 returned 401
org.elastic4play.AuthenticationError: Authentication failure
at org.elastic4play.services.auth.MultiAuthSrv$$anonfun$authenticate$6.applyOrElse(MultiAuthSrv.scala:71)
at org.elastic4play.services.auth.MultiAuthSrv$$anonfun$authenticate$6.applyOrElse(MultiAuthSrv.scala:67)
at scala.concurrent.Future.$anonfun$recoverWith$1(Future.scala:413)
at scala.concurrent.impl.Promise.$anonfun$transformWith$1(Promise.scala:37)
at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:60)
at akka.dispatch.BatchingExecutor$AbstractBatch.processBatch(BatchingExecutor.scala:55)
at akka.dispatch.BatchingExecutor$BlockableBatch.$anonfun$run$1(BatchingExecutor.scala:91)
at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:12)
at scala.concurrent.BlockContext$.withBlockContext(BlockContext.scala:81)
at akka.dispatch.BatchingExecutor$BlockableBatch.run(BatchingExecutor.scala:91)

All 18 comments

@To-om Could we add a bit more logs to try figure out what happens there?

I am having the same issue. I am using a 3.4.0-RC1 Hive veversion, please find my logs below:

[error] o.e.s.a.MultiAuthSrv - **Authentication failure**
java.lang.IllegalArgumentException: Invalid URL 
at play.api.libs.ws.ahc.StandaloneAhcWSClient.validate(StandaloneAhcWSClient.scala:84)
at play.api.libs.ws.ahc.StandaloneAhcWSClient.url(StandaloneAhcWSClient.scala:42)
at play.api.libs.ws.ahc.AhcWSClient.url(AhcWSClient.scala:37)
at services.mappers.GroupUserMapper.$anonfun$getUserFields$2(GroupUserMapper.scala:43)
at scala.Option.fold(Option.scala:158)
at services.mappers.GroupUserMapper.getUserFields(GroupUserMapper.scala:43)
at services.mappers.MultiUserMapperSrv.getUserFields(MultiUserMapperSrv.scala:27)
at services.OAuth2Srv.$anonfun$getOrCreateUser$1(OAuth2Srv.scala:123)
at scala.Option.fold(Option.scala:158)
at services.OAuth2Srv.withOAuth2Config(OAuth2Srv.scala:66)
Caused by: java.lang.IllegalArgumentException:  could not be parsed into a proper Uri, missing scheme
at play.shaded.ahc.org.asynchttpclient.uri.Uri.create(Uri.java:40)
at play.shaded.ahc.org.asynchttpclient.uri.Uri.create(Uri.java:32)
at play.api.libs.ws.ahc.StandaloneAhcWSClient.validate(StandaloneAhcWSClient.scala:81)
at play.api.libs.ws.ahc.StandaloneAhcWSClient.url(StandaloneAhcWSClient.scala:42)
at play.api.libs.ws.ahc.AhcWSClient.url(AhcWSClient.scala:37)
at services.mappers.GroupUserMapper.$anonfun$getUserFields$2(GroupUserMapper.scala:43)
at scala.Option.fold(Option.scala:158)
at services.mappers.GroupUserMapper.getUserFields(GroupUserMapper.scala:43)
at services.mappers.MultiUserMapperSrv.getUserFields(MultiUserMapperSrv.scala:27)
at services.OAuth2Srv.$anonfun$getOrCreateUser$1(OAuth2Srv.scala:123)
[info] o.e.ErrorHandler - POST /api/ssoLogin?code=fc0c6142-4056-4017-9ee0-d181a1d27b86.3c566da0-3eb0-4ed2-83c4-6f942fc4462f.ecde927e-733e-4477-b0ff-93238254eaa6 returned 401
org.elastic4play.AuthenticationError: Authentication failure
at org.elastic4play.services.auth.MultiAuthSrv$$anonfun$authenticate$6.applyOrElse(MultiAuthSrv.scala:71)
at org.elastic4play.services.auth.MultiAuthSrv$$anonfun$authenticate$6.applyOrElse(MultiAuthSrv.scala:67)
at scala.concurrent.Future.$anonfun$recoverWith$1(Future.scala:413)
at scala.concurrent.impl.Promise.$anonfun$transformWith$1(Promise.scala:37)
at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:60)
at akka.dispatch.BatchingExecutor$AbstractBatch.processBatch(BatchingExecutor.scala:55)
at akka.dispatch.BatchingExecutor$BlockableBatch.$anonfun$run$1(BatchingExecutor.scala:91)
at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:12)
at scala.concurrent.BlockContext$.withBlockContext(BlockContext.scala:81)
at akka.dispatch.BatchingExecutor$BlockableBatch.run(BatchingExecutor.scala:91)
java.lang.IllegalArgumentException: Invalid URL

Please check which property is not a valid URL in your config

I am not able to figure it out that which URL is not valid. But according to default configuration redirect URL is redirecting to the Login page, I don't know why is this. remaining URLs are my OAuth provider related. My config as follows:

auth {

  provider = [local, oauth2]

  oauth2 {
  clientId = "hive"
  clientSecret = "***************"
  redirectUri = "http://127.0.0.1:9000/index.html#/login"
  responseType = "code"
  grantType = "authorization_code"
  authorizationUrl = "https://<domain.name>/protocol/openid-connect/auth"
  tokenUrl = "https://<domain.name>/protocol/openid-connect/token"
  userUrl = "https://<domain.name>/protocol/openid-connect/userinfo"
  scope = "openid"
  }

  sso {
    mapper = group
    autocreate = true
    defaultRoles = ["read"]
    autologin = true
    attributes {
        login = "userid"
        name = "preferred_username"
        groups = "groups" // name of the attribute containing the user groups
        }
    groups.mappings { // map groups to roles
          mygroup1= ["read", "write", "admin"]
          mygroup2= ["read", "write"]
          }
    }
}
java.lang.IllegalArgumentException: Invalid URL

Please check which property is not a valid URL in your config

I am not able to figure it out that which URL is not valid. But according to default configuration redirect URL is redirecting to the Login page, I don't know why is this. remaining URLs are my OAuth provider related. My config as follows:

auth {

provider = [local, oauth2]

oauth2 {
clientId = "hive"
clientSecret = "*****"
redirectUri = "http://127.0.0.1:9000/index.html#/login"
responseType = "code"
grantType = "authorization_code"
authorizationUrl = "https:///protocol/openid-connect/auth"
tokenUrl = "https:///protocol/openid-connect/token"
userUrl = "https:///protocol/openid-connect/userinfo"
scope = "openid"
}

sso {
mapper = group
autocreate = true
defaultRoles = ["read"]
autologin = true
attributes {
login = "userid"
name = "preferred_username"
groups = "groups" // name of the attribute containing the user groups
}
groups.mappings { // map groups to roles
mygroup1= ["read", "write", "admin"]
mygroup2= ["read", "write"]
}
}
}

The login page is the callback URL your OAuth provided will call after you authentification. Once you come back to login page, TheHive will use the authorization code to get the authenticated user details and log you in.

The error is clear

Caused by: java.lang.IllegalArgumentException: could not be parsed into a proper Uri, missing scheme

Thanks for the quick reply.
I see the error but I don't understand what should be done to correct an error. it's been really difficult to solve this issue. I have checked the Uris in the config, all are fine. I am clueless to solve this issue.

Simpler Mapping is working fine but Group mapping is not working and throwing an error called invalid URL. Should I pass url for the group in the config like below:
groups {
url = "https://auth-site.com/api/Groups"

@ananth07reddy You need in fact a URL to fetch the user groups as said in your last comment

Thank you for the quick reply. But I am using Keycloak as the identity provider and don't see any group uri to pass like above.

Can you please send me an example full configuration because it is really confusing? I don't see that being used group.url in the config.

Are we talking about 2 different issues here? My original issue was about a missing log message, but i think we're delving in to a different stated error message. Just don't want my original to get lost in the shuffle 馃榿

I agree @drewstinnett

The OAuth feature is something that is not exhaustive, so we discover new use cases every time, new configurations etc...

Hi @drewstinnett, I'm working on a PR that will improve OAuth2 support. After a deep study of the OAuth2 code, I think your error is presented when a field can't be found in user info. Could you check that sub and name attributes are received by TheHive when it retreives user info?

auth {
  ...
  sso {
    ...
    attributes {
      login = "sub"
      name = "name"
    }
  }
}

Note: I'm currently fixing the message not showing up in the PR

Apologies for the delayed replay @1earch you were exactly right! The "name" attribute wasn't getting passed back. When I adjusted both name and login to "sub", the authentication succeeded, many thanks!

Happy to help :slightly_smiling_face:
If your issue is fixed, don't hesitate to close it! :wink:

Thanks @1earch and @drewstinnett

I'm closing the issue.

Was this page helpful?
0 / 5 - 0 ratings