Cas 5.1 How to get client's service url.

667 views
Skip to first unread message

snaffy

unread,
Nov 23, 2017, 9:41:23 AM11/23/17
to CAS Community
I would like to know how I can retrieve the encoded address of the service parameter on the authentication step on the CAS serve side.
More precisely I have created CustomAuthenticationHandler and at this stage, I need to know from what domain the authentication request came from. For example from this address https://localhost:8445/cas/login?service=https%3A%2F%2Flocalhost%3A8445%2Fcasclient%2F I need to extract "localhost"


public class CustomAuthenticationHandler implements AuthenticationHandler {

    protected PrincipalFactory principalFactory = new DefaultPrincipalFactory();

    @Autowired
    PropertiesConfiguration propertiesConfiguration;
    private transient Logger logger = LoggerFactory.getLogger(this.getClass());

   
    @Override
    public HandlerResult authenticate(Credential credential) throws GeneralSecurityException, PreventedException {

        UsernamePasswordCredential usernamePasswordCredential = (UsernamePasswordCredential) credential;
       // Here I would like to have access to the encoded address
   }

Thanks in advance for help. 

Andy Ng

unread,
Nov 24, 2017, 5:29:27 AM11/24/17
to CAS Community
I also don't know a way to retrive the hostname. However I would like to know what is your use case for the hostname

If, for example, you have 3 hosts that need 3 different customized authentication

1) https://i-only-use-saml.example.com
2) https://i-only-use-oauth.example.com
3) https://i-only-use-usernamepassword.example.com

Then you can just registered the above three services, and use the "requiredHandler" param to redirect the three use case to a specific authentication handler. https://apereo.github.io/cas/development/installation/Service-Management.html (if you are planning to use CAS 5.2.0) 

However, if you need to do much more with the hostname, that service management cannot help with your use case, then I might not be able to help you... Maybe you need to read the source code to see how it can be retrived.

- Andy

snaffy

unread,
Nov 26, 2017, 1:36:51 PM11/26/17
to CAS Community
On the issue of using a hostname, I need it to retrieve a user from the database - the user is searched using his name and an additional parameter that I can specify using the hostname.

As for your suggestions, they are also useful. This is the next step I am going to take, namely:
I would like to users from the specified domain to be properly redirected.
If the user comes from https://localhost:8445/casclient2/ then let him show standard cas login page with appropriate handler:

{
  "@class" : "org.apereo.cas.services.RegexRegisteredService",
  "name" : "JDBC",
  "id" : 1003,
  "description" : "Sample 1",
  "evaluationOrder" : 51,
  "requiredHandlers" : [ "java.util.HashSet", [ "QueryAndEncodeDatabaseAuthenticationHandler" ] ]
}
- here's no problem everything works


However if the user comes from https://localhost:8445/casclient2/ then I would like to have authenticated using SAML and external Idp - delegated authentication.I have tested it using the automatically generated button - in the second case I would like the users not even see the form from cas. 

Andy Ng

unread,
Nov 26, 2017, 5:50:25 PM11/26/17
to CAS Community
In that case, I would suggest using a custom template. And make all the username, password parameters to be hidden. Or maybe create a <span> loading
... </span> so user know they are being redirected.

Here are how to set up custom template:
https://groups.google.com/a/apereo.org/forum/m/#!topic/cas-user/k-yfoou7Zy0

See if that helps you.

- Andy

Andy Ng

unread,
Nov 26, 2017, 8:52:52 PM11/26/17
to CAS Community
Hi again,

I have just dig deeper in the source code, and I found the way to extract the service URL, here how it can be done in CAS 5.2.0-RC4 (I am too lazy to test it in other version, please change the code accordingly)



public class CustomAuthenticationHandler implements AuthenticationHandler {

    protected PrincipalFactory principalFactory = new DefaultPrincipalFactory();

    @Autowired
    PropertiesConfiguration propertiesConfiguration;
    private transient Logger logger = LoggerFactory.getLogger(this.getClass());

   
    @Override
    public HandlerResult authenticate(Credential credential) throws GeneralSecurityException, PreventedException {

        UsernamePasswordCredential usernamePasswordCredential = (UsernamePasswordCredential) credential;
       // Here I would like to have access to the encoded address


        final RequestContext context = RequestContextHolder.getRequestContext();
        final WebApplicationService service = WebUtils.getService(context); //WebUtils use the CAS one

        String theUrlThatYouNeed = service.getId();
        //Of course you need to extract the hostname from the url
   }

Additional Info:
I will also shows you the steps I acquire this information, so you might reference if you want.
1) I search all types of AuthenticationHandler and see if any of them is using the serviceParam url
2) I sumble accross this class YubiKeyAuthenticationHandler (actually, I don't know what this handler does... but it doesn't matter much)
3) I see that it uses RequestContext, so I immediate see what this class does (Since I know request context -> GET parameter -> service parameter -> goal)
4) I see that with RequestContext, I can get WebApplicationService and Service
5) I see this line final String serviceUrl = URLDecoder.decode(service.getId(), StandardCharsets.UTF_8.name()); 
6) hence I know the I can use service.getId() to get the service URL

Hope this helps you!

-Andy

snaffy

unread,
Nov 27, 2017, 4:00:16 PM11/27/17
to CAS Community
Thank you Andy for your time, everything works as I wanted.
Reply all
Reply to author
Forward
0 new messages