By: Sankar Balasubramaniam user 20 Feb 2017 at 1:51 a.m. CST

10 Responses
Sankar Balasubramaniam gravatar
I have an existing web service from a legacy system that is used for authentication and it also provides some additional user based information as part of the response. I would like to know the following 1) Can Gluu be configured to use an existing authentication service ? 2) Does Gluu provide options to capture this additional information returned in the response and return the additional information through /userinfo endpoint or even encode it within the JWT?

By Mohib Zico Account Admin 20 Feb 2017 at 2:43 a.m. CST

Mohib Zico gravatar
Hi Sankar, As Gluu Server can enhance to [external authentication](https://gluu.org/docs/authn-guide/intro/) so might be possible. But we need to know which kind of legacy system you are using and which extra user's information it's releasing. Might be helpful for us to answer.

By Sankar Balasubramaniam user 20 Feb 2017 at 3:23 a.m. CST

Sankar Balasubramaniam gravatar
Hi Mohib, I have a legacy REST service to which I need to pass user credentials as parameters. The response is an XML String like below <ROOT xmlns="http://abc.com/abc"> <STATUS>200</STATUS> <USER>User 1</USER> <CARDS> <CARD>C1</CARD> <CARD>C2</CARD> </CARDS> <FACILITIES> <FACILITY>F1</FACILITY> <FACILITY>F2</FACILITY> </FACILITIES> </ROOT> The authentication status (like 200 == authentication successful, 100 = authentication failure) with additional data like facilities = [F1, F2, F3], cards = [C1, C2, C3], etc which is specific for the user. So after successfully authenticating with this external REST service, I would like to construct/enhance the JWT with data like 'facilities = [F1, F2, F3], cards = [C1, C2, C3]'. FYI, I have managed to do the same with the spring-cloud-oauth2 server where there are placeholders for token enhancement. I would like to know if i can do something similar here. Please let me know if you need any additional information. Thank you for your assistance.

By Michael Schwartz Account Admin 20 Feb 2017 at 12:32 p.m. CST

Michael Schwartz gravatar
As Mohib pointed out, you can do this with a custom authentication script. A good place to start is the [docs page](https://gluu.org/docs/authn-guide/customauthn/). In a nutshell, there is a method called `authenticate` which returns true or false. You can implement any business logic you can express in python. Another similar feature is dynamic scopes. You can use this to create business logic for what claims to return at the Userinfo endpoint. You can request a signed Userinfo response if you want a JWT. Or you can simply pass the access token to your backend app so it can also call Userinfo. If you need any help, Gluu has many great [partners](https://www.gluu.org/partners-service/) Or let us know if you are interested in commercial support, and we can perhaps provide some more tactical assistance. - Mike

By Sankar Balasubramaniam user 27 Feb 2017 at 3:11 p.m. CST

Sankar Balasubramaniam gravatar
Hi Mike, The custom authentication script seems to be the right solution. Just one more question. Is it possible to provide 2 different authentication methods for different set of users ? Say, certain users should use the interception scripts and other users should use LDAP? Even if the authentication methods can be chained (one after the other) that might also work. Is there a way to configure this setup in Gluu?

By Mohib Zico Account Admin 01 Mar 2017 at 2:14 p.m. CST

Mohib Zico gravatar
>> Is it possible to provide 2 different authentication methods for different set of users ? Say, certain users should use the interception scripts and other users should use LDAP? Even if the authentication methods can be chained (one after the other) that might also work. Is there a way to configure this setup in Gluu? I don't see any design like this yet. Because: - How Gluu Server will decide which user to send where? Who will feed such info to Gluu Server? Remote RP? - 'Chained method' is something like using 2FA in Gluu. User pass two authentication methods one after another. First Username/Password and then strong authentication. Or.. you can use two Gluu Servers for two types of users?

By Sankar Balasubramaniam user 06 Mar 2017 at 10:18 a.m. CST

Sankar Balasubramaniam gravatar
Hi Mohib, While this could be a very specific requirement, I think we can decide what authentication method to use based on additional parameters like say domain. But I agree to your point that it can also be achieved using 2 different Gluu servers. Just one more question. The interception script looks like an ideal option for my requirement and I need to call a SOAP web service to perform the authentication. Based on the documentation that looks very much possible. Do you have an example on how a SOAP web service can be used in a Jython script to authenticate the user? Do you have any simpler soap clients under oxauth that can be used for soap service calls ?

By Sankar Balasubramaniam user 07 Mar 2017 at 7:33 a.m. CST

Sankar Balasubramaniam gravatar
I did manage to write a Jython script that calls a soap web service and does the authentication using suds-jurko module. The standalone jython script works fine. I am not sure whether how Gluu server would install the suds module. But I still added this part to the basic authentication script on Gluu server like below and checked the 'Enabled' check box as Gluu admin. ------------------------------------------------------------------ from org.jboss.seam.security import Identity from org.xdi.model.custom.script.type.auth import PersonAuthenticationType from org.xdi.oxauth.service import UserService from org.xdi.util import StringHelper from suds.client import Client import java class PersonAuthentication(PersonAuthenticationType): def __init__(self, currentTimeMillis): self.currentTimeMillis = currentTimeMillis def init(self, configurationAttributes): print "Basic. Initialization" print "Basic. Initialized successfully" return True def destroy(self, configurationAttributes): print "Basic. Destroy" print "Basic. Destroyed successfully" return True def getApiVersion(self): return 1 def isValidAuthenticationMethod(self, usageType, configurationAttributes): return True def getAlternativeAuthenticationMethod(self, usageType, configurationAttributes): return None def pdmAuthenticate(user, password): WDSL = 'http://host/path/service?wsdl' client = Client(WDSL) return client.service.getAuthentication(arg0=user, arg1=password) def authenticate(self, configurationAttributes, requestParameters, step): if (step == 1): print "Basic. Authenticate for step 1" credentials = Identity.instance().getCredentials() user_name = credentials.getUsername() user_password = credentials.getPassword() logged_in = False if (StringHelper.isNotEmptyString(user_name) and StringHelper.isNotEmptyString(user_password)): logged_in = pdmAuthenticate(user_name, user_password) if (not logged_in): return False return True else: return False def prepareForStep(self, configurationAttributes, requestParameters, step): if (step == 1): print "Basic. Prepare for Step 1" return True else: return False def getExtraParametersForStep(self, configurationAttributes, step): return None def getCountAuthenticationSteps(self, configurationAttributes): return 1 def getPageForStep(self, configurationAttributes, step): return "" def logout(self, configurationAttributes, requestParameters): return True ------------------------------------------------------------------ After this further calls to Gluu server fails with the following error Error Encountered An unexpected error has occurred at 2017-03-07 02:17:42 PM. Failed to authenticate The oxauth.log has the following error at org.jboss.el.parser.AstValue.invoke(AstValue.java:96) [jboss-el-1.0_02.CR6.jar:1.0_02.CR6] 2017-03-07 14:17:31,731 ERROR [qtp1395089624-18] [org.xdi.oxauth.service.external.ExternalAuthenticationService] (ExternalAuthenticationService.java:345) - Failed to determine alternative authentication mode for acr_values: 'basic' 2017-03-07 14:17:42,345 ERROR [qtp1395089624-14] [org.xdi.oxauth.service.external.ExternalAuthenticationService] (ExternalAuthenticationService.java:252) - null java.lang.NullPointerException: null at org.xdi.oxauth.service.external.ExternalAuthenticationService.executeExternalGetPageForStep(ExternalAuthenticationService.java:250) 2017-03-07 14:17:42,406 ERROR [qtp1395089624-15] [org.xdi.oxauth.service.external.ExternalAuthenticationService] (ExternalAuthenticationService.java:137) - null java.lang.NullPointerException: null at org.xdi.oxauth.service.external.ExternalAuthenticationService.executeExternalIsValidAuthenticationMethod(ExternalAuthenticationService.java:135) [classes/:?] at org.xdi.oxauth.service.external.ExternalAuthenticationService.determineExternalAuthenticatorForWorkflow(ExternalAuthenticationService.java:339) [classes/:?] 2017-03-07 14:17:42,408 WARN [qtp1395089624-15] [org.xdi.oxauth.service.external.ExternalAuthenticationService] (ExternalAuthenticationService.java:341) - Current acr_values: 'basic' isn't valid 2017-03-07 14:17:42,408 ERROR [qtp1395089624-15] [org.xdi.oxauth.service.external.ExternalAuthenticationService] (ExternalAuthenticationService.java:150) - null java.lang.NullPointerException: null at org.xdi.oxauth.service.external.ExternalAuthenticationService.executeExternalGetAlternativeAuthenticationMethod(ExternalAuthenticationService.java:148) [classes/:?] at org.xdi.oxauth.service.external.ExternalAuthenticationService.determineExternalAuthenticatorForWorkflow(ExternalAuthenticationService.java:343) [classes/:?] 2017-03-07 14:17:42,421 ERROR [qtp1395089624-15] [org.xdi.oxauth.service.external.ExternalAuthenticationService] (ExternalAuthenticationService.java:345) - Failed to determine alternative authentication mode for acr_values: 'basic' Any idea what went wrong here?

By Mohib Zico Account Admin 08 Mar 2017 at 4:41 a.m. CST

Mohib Zico gravatar
Can you please share your script in pastebin or so? We will try it locally. Generally it's a good idea to create a brand new script rather than modifying default scripts which we are providing out of the box with Gluu Server. Such as... 'basic' script should run along with some other script ( not as standalone script ). i.e. you have a Google+ script which are being used to authenticate your users with their GoogleID which is enabled as 'Authentication Mode'. And you are supplying 'basic' in oxTrust Authentication Mode.

By Sankar Balasubramaniam user 08 Mar 2017 at 6:38 a.m. CST

Sankar Balasubramaniam gravatar
The pastebin version can be found here (http://pastebin.com/embed_js/n1FZ7JLb) and a cleaner code snippet can be found below ``` # oxAuth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. # Copyright (c) 2016, Gluu # # Author: Yuriy Movchan # from org.jboss.seam.security import Identity from org.xdi.model.custom.script.type.auth import PersonAuthenticationType from org.xdi.oxauth.service import UserService from org.xdi.util import StringHelper from suds.client import Client import java class PersonAuthentication(PersonAuthenticationType): def __init__(self, currentTimeMillis): self.currentTimeMillis = currentTimeMillis def init(self, configurationAttributes): print "Basic. Initialization" print "Basic. Initialized successfully" return True def destroy(self, configurationAttributes): print "Basic. Destroy" print "Basic. Destroyed successfully" return True def getApiVersion(self): return 1 def isValidAuthenticationMethod(self, usageType, configurationAttributes): return True def getAlternativeAuthenticationMethod(self, usageType, configurationAttributes): return None def pdmAuthenticate(user, password): WDSL = 'http://server:port/path/service?wsdl' client = Client(WDSL) return client.service.getAuthentication(arg0=user, arg1=password) def authenticate(self, configurationAttributes, requestParameters, step): if (step == 1): print "Basic. Authenticate for step 1" credentials = Identity.instance().getCredentials() user_name = credentials.getUsername() user_password = credentials.getPassword() logged_in = False if (StringHelper.isNotEmptyString(user_name) and StringHelper.isNotEmptyString(user_password)): logged_in = pdmAuthenticate(user_name, user_password) if (not logged_in): return False return True else: return False def prepareForStep(self, configurationAttributes, requestParameters, step): if (step == 1): print "Basic. Prepare for Step 1" return True else: return False def getExtraParametersForStep(self, configurationAttributes, step): return None def getCountAuthenticationSteps(self, configurationAttributes): return 1 def getPageForStep(self, configurationAttributes, step): return "" def logout(self, configurationAttributes, requestParameters): return True ``` In my case, I would like this custom authentication through web service call to be the primary and only authentication mode. How can I achieve the same?

By Mohib Zico Account Admin 20 Mar 2017 at 1:28 p.m. CDT

Mohib Zico gravatar
Seems like there is some syntax error in your code. Here is what I am getting from oxauth_script.log ( /opt/gluu/jetty/oxauth/logs/ ) whenever I am trying to load your script: http://pastebin.com/qzL1XnUL