CAS Rest Protocol Does not work without Generic Service Definition

98 views
Skip to first unread message

Cemal Önder

unread,
Dec 17, 2019, 1:19:53 AM12/17/19
to CAS Community
I want to use REST Protocol in my services. For this, I enabled Rest Protocol and trying to get TGT. Also, all examples were based on generic service registration which I don't want in prod environment.


Here is the generic service registry example that should not be used in prod environment. And I did not use this in my environment:

    {
     
/*
        Generic service definition that applies to https/imaps urls
        that wish to register with CAS for authentication.
      */

     
"@class" : "org.apereo.cas.services.RegexRegisteredService",
     
"serviceId" : "^(https|imaps)://.*",
     
"name" : "HTTPS and IMAPS",
     
"id" : 10000001,
   
}


Instead, I have the following one:

    {
     
"@class": "org.apereo.cas.services.RegexRegisteredService",
     
// this service will match all the requests contains test in the request url
     
"serviceId": "^https?:\\/\\/.*test($|\\/).*$",
     
"name": "Test",
     
"id": 1,
     
"description": "Test service",
     
"evaluationOrder": 2,
     
"requiredHandlers": [
       
"java.util.HashSet",
       
[
         
"TestHandler"
       
]
     
],
     
"attributeReleasePolicy": {
       
"@class": "org.apereo.cas.services.ReturnAllAttributeReleasePolicy"
     
},
     
"properties": {
       
"@class": "java.util.HashMap",
       
"jwtAsServiceTicket": {
         
"@class": "org.apereo.cas.services.DefaultRegisteredServiceProperty",
         
"values": [
           
"java.util.HashSet",
           
[
             
"true"
           
]
         
]
       
}
     
}
   
}


I can not request a ticket granting ticket as explained here:

    POST /cas/v1/tickets HTTP/1.0
   
'Content-type': 'Application/x-www-form-urlencoded'
    username
=battags&password=password&additionalParam1=paramvalue


I got the following exception:

    Unauthorized Service Access. Service [] is not found in service registry


When I debug the code, I can see that TGT is created and my registered service works fine. An exception is thrown because of the registered service check for againts CAS Server in JWTBuilder

        val registeredService = payload.getRegisteredService() == null
           
? locateRegisteredService(serviceAudience)
           
: payload.getRegisteredService();
       
RegisteredServiceAccessStrategyUtils.ensureServiceAccessIsAllowed(registeredService);


Here CAS tries to check if service access is allowed. payload.getRegisteredService returns null and locateRegisteredService is called with serviceAudience, than ensureServiceAccessIsAllowed throws the exception.

Problem is: serviceAudience is always filled with CAS server prefix which means this there must a service definition that matches with CAS server prefix. All examples work when I enable generic service definition but when I remove it, TGT does not return because of the above check.  

Any idea, solution? I don't want to allow everyone able to create TGT, I can add service definition that only matches with CAS prefix also but first it is better to understand if I miss something or if this is a bug.

WalTech

unread,
Dec 17, 2019, 2:38:38 AM12/17/19
to CAS Community
I saw this too. With 6.2 you need to specifify the allowed service names in the CAS configuration. This is done by enabling the JSON config option and creating a json style config for the service name.
The service name is 'nothing' more than the url of the service. Like https://yourdomain.com .
On each TGT request you must send this url in the POST.

WalTech

unread,
Dec 17, 2019, 2:40:09 AM12/17/19
to CAS Community
I will see that i post my configs so you can compare them with yours
Message has been deleted

Cemal Önder

unread,
Dec 17, 2019, 2:53:51 AM12/17/19
to CAS Community
Okay if it is known behavior than I had to consider this since my CAS has multiple instances and I should allow them all. Thanks for your interest.

Ray Bon

unread,
Dec 17, 2019, 1:17:02 PM12/17/19
to cas-...@apereo.org
Cemal,

Did you try with, username=battags&password=password&service=https://something.com/test

You have only one service defined, it must have 'test' in the url. Any other service, including the CAS default page, is not allowed.

If you do not provide a service, CAS will redirect to its default page. You can also add a config item, cas.view.defaultRedirectUrl. I am not sure where in the docs this is.

Ray
-- 
Ray Bon
Programmer Analyst
Development Services, University Systems

I respectfully acknowledge that my place of work is located within the ancestral, traditional and unceded territory of the Songhees, Esquimalt and WSÁNEĆ Nations.

Cemal Önder

unread,
Dec 17, 2019, 11:25:45 PM12/17/19
to CAS Community
Yes rbon I tried, but again it stucks at the same line
 
Also it seems like service is only required when we are trying to get authenticated via /login (which is also have redirections, but not /ticket endpoint). According to the docs, it is not required for /ticket Rest endpoint for getting TGT, but it is required to get ST: https://apereo.github.io/cas/6.0.x/protocol/REST-Protocol.html#request-a-ticket-granting-ticket

WalTech

unread,
Dec 18, 2019, 5:21:11 AM12/18/19
to CAS Community
I use the JSON service registry to set up the service name:
In build.gradle:  compile "org.apereo.cas:cas-server-support-json-service-registry:${casServerVersion}"
Then in /etc/cas/services i created a file wildflyApplication-100.json with the content:
{
 
"@class" : "org.apereo.cas.services.RegexRegisteredService",
 
"serviceId" : "https://mywebserver\\.com*",
 
"name" : "wildflyApplication",
 
"id" : 100,
 
"evaluationOrder" : 1
}

and in my CAS client code i use https://mywebserver.com as the serviceURL .

I modified /etc/cas/application.properties and added these lines:
cas.authn.attributeRepository.jdbc[0].attributes.role=personRole
cas
.authn.attributeRepository.jdbc[0].singleRow=false
cas
.authn.attributeRepository.jdbc[0].columnMappings.attribute=value
cas
.authn.attributeRepository.jdbc[0].sql=SELECT * FROM Users left join User_roles on Users.userid=User_roles.userid WHERE Users.{0}
cas
.authn.attributeRepository.jdbc[0].username=userid
cas
.authn.attributeRepository.jdbc[0].driverClass=com.mysql.jdbc.Driver
cas
.authn.attributeRepository.jdbc[0].user=*******
cas
.authn.attributeRepository.jdbc[0].password=*****
cas
.authn.attributeRepository.jdbc[0].url=jdbc:mysql://localhost:3306/cas_auth1
cas
.authn.attributeRepository.jdbc[0].attributes.firstname=firstName
cas
.authn.attributeRepository.jdbc[0].attributes.lastname=lastName
cas
.authn.attributeRepository.jdbc[0].attributes.group=value
cas
.authn.attributeRepository.defaultAttributesToRelease=personRole,firstname,lastname,group


First i do a post to casUrlPrefix +"/v1/tickets" + "?format=json", and i set the header to addHeader("Accept", "application/json") which makes sure i will get a json formatted response from CAS. 
I extract the TGT ticket with EntityUtils and proceed to a new post. 

This new post is build like this casUrlPrefix +"/v1/tickets" + "?format=json" and has 3 url parameters: username, password and service. They are posted to CAS and the response is a json formatted ST- ID

After that i set  validateUrl=casUrlPrefix + "/p3/serviceValidate?service="
and i do a GET to HttpGet(validateUrl+serviceURL+"&ticket="+STid+"&format=json")
This gives me all the user attributes JSON formatted as stated in application.properties with the cas.authn.attributeRepository.jdbc[0] lines. 

Benefit of this that i can now "see" to which groups the user belongs
Message has been deleted

WalTech

unread,
Dec 18, 2019, 5:31:13 AM12/18/19
to CAS Community
{
"serviceResponse": {
"authenticationSuccess": {
"user": "Wallie",
"attributes": {
"credentialType": [
"UsernamePasswordCredential"
],
"isFromNewLogin": [
true
],
"authenticationDate": [
1576664897.419792
],
"authenticationMethod": [
"QueryDatabaseAuthenticationHandler"
],
"successfulAuthenticationHandlers": [
"QueryDatabaseAuthenticationHandler"
],
"personRole": [
"manager",
"codenoob"
],
"longTermAuthenticationRequestTokenUsed": [
false
]
}
}
}
}

Cemal Önder

unread,
Dec 18, 2019, 5:53:45 AM12/18/19
to CAS Community
Thanks WalTech, only difference so far seems to Accept header and token=true which is for JSON TGT but I will compare it step by step with my environment and share the results.
Reply all
Reply to author
Forward
0 new messages