not recognized cas ticket - single-sign-on

I have a REST api in my web application where I get cas ticket generated by another webapp.
That webapp intern use cas20proxyticketvalidator to validate the ticket. Therefore, I also use Cas20ProxyTicketValidator in my custom filter to validate the ticket.
But it always give me following error:
ticket = ST-148008-jWXKeEdHkxmuktvYqXF6-cas
org.jasig.cas.client.validation.TicketValidationException:
ticket 'ST-148008-jWXKeEdHkxmuktvYqXF6-cas' not recognized
at org.jasig.cas.client.validation.Cas20ServiceTicketValidator.parseResponseFromServer(Cas20ServiceTicketValidat
or.java:86)
at org.jasig.cas.client.validation.AbstractUrlBasedTicketValidator.validate(AbstractUrlBasedTicketValidator.java
:217)
Why my ticket is not recognized?

The way that cas validates tickets is:
Your client (or the other web app) requests a ticket from the relay
server for a particular service, for example case
http%3A%2F%2Fwww.mywebapp.com
The cas server generates a row that stores the user's ssoguid, the service and the ticket. It returns the ticket to the client (or
other web app)
The client (or other webapp) sends the ticket to your server
Your server then sends a request to the serviceValidate endpoint of the cas server with the ticket and the service,
http%3A%2F%2Fmywebapp.com
The cas server uses the ticket and service pair to find the row it generated. If it finds the row it: a) checks to see if the
service is real by sending a request to that url b) deletes the row
to invalidate the ticket after this validation check c) it returns
the user attached to the ticket to your server. Now the ticket can
not be validated again.
The problem you are experiencing could arise for several reasons:
The ticket has already been validated (I don't think that is the
case for you)
The service you send when generating the ticket is different to the service you send to the serviceValidate endpoint (they have to
be identical). (I would guess that this is the problem you are
experiencing, especially if another webapp generated the ticket. The
cas server would have http%3A%2F%2Fotherwebapp.com on file but would
be trying to find a row with http%3A%2F%2Fmywebapp.com, which
doesn't exist because you didn't create it)
The service sent can
not be contacted by the relay server (I'm not exactly sure of the
details about how this works or exactly when the check it done but
it is recommended that you use a service that can be contacted)

Check the serviceUrl generated, so change the log level for package org.jasig.
With SpringBoot, in the application.properties add
logging.level.org.jasig=DEBUG
In the console
org.jasig.cas.client.util.CommonUtils : serviceUrl generated: https://xxx
Verify and adapt your cas.client-host-url in the application.properties
## CAS[2.0]
cas.server-url-prefix=https://cashost.com/cas
cas.server-login-url=https://cashost.com/cas/login
cas.client-host-url=xxx
cas.validation-type=CAS
Be careful with cas.client-host-url, no slash at the end of url.
Don't forget mvn clean package after modifying .properties

Related

Configuring Shibboleth Metadata File

We have recently migrated to a new hosting environment so have installed a fresh instance of Shibboleth. When we generate sp metadata files, the urls are non-secure (ie http) even though the url used to generate the metadata uses https.
When using the test connection from our own Azure AD system, we see the obvious error: "The reply URL specified in the request does not match the reply URLs configured for the application:"
I have limited knowledge of configuring the system beyond working on shibboleth2.xml and attribute-map.xml so would be very grateful if anyone can point me in the right direction to fix this.
I'm not sure if you managed to configure it but i'm currently working on this as well, and i think i can help.
So the ReplyURL you need to provide in the Azure Portal, is the reply URL that accepts the authentiaction reply message from the identity provider.
In the case of Shibboleth it is:
http[s]://yoursitename/Shibboleth.SSO/Auth/Saml
So if your webpage is for instance:
https://localhost/Foo
The replyURL should be:
https://localhost/Shibboleth.SSO/Auth/Saml
Notice that the page "Foo" is not in the replyURL.
After the authentication the browser should send the IDP reply to https://localhost/Shibboleth.SSO/Auth/Saml, after which Shibboleth should redirect you back to https://localhost/Foo
At least that's the default behaviour.

Keycloak authentication: how can a external user get an token without exposing client secret

I have a query about how keycloak is supposed to be working with client without GUI access.
Basically I have:
A keycloak server configured with a realm, clients(Access type confidential) and Users
A server application with a GUI that also provide API, secure with keycloak (client, user, blablabla)
This is kind of working already as I am able to log on the GUI, have the redirect, etc..
Even accessing the APIs works well, when I have access to a GUI: I log on my UI, follow the redirect and get my UI to display the token. The the human (to differentiate the user from an application), can use the token in any API client.
In this context the user never sees the client secret, which is instinctively the right way. (note that I am very opened to people telling me my instinct is wrong!)
What I am NOT able to do so far is to find the way a server application (without GUI) can get a valid token?
The authorization_endpoint, as far as I understand it, requires both the client id and the client secret) to get a token, which I would rather avoid: I don't think giving my client secret to all my "customers" is the proper way to do it.
Alternatively I could create an API on my client that woudl ask for user credential and ask for the token in its behalf, but that would expose the clients credentials to my application, which is against the whole concept!
I tried setting my client Access type as public, but when I use the API call below I also get a error:
POST /auth/realms/realmname/protocol/openid-connect/tokenAPI
'grant_type=client_credentials'
'client_id=client_id'
'username=username'
'password=password'
{
"error": "unauthorized_client",
"error_description": "Public client not allowed to retrieve service account"
}
Would anyone know how this is supposed to be done ?
Thanks in advance.
Max
(...) A server application (without GUI) can get a valid token... typically using the Client Credentials flow.
But we would define in this case a dedicated Client for your server (client?) application to authenticate against. The returned token (not bound to a specific user) will serve for authorizations on allowed applications (i.e. your classic GUI or API clients).
So, basically you should (in very short):
define a specific confidential Client in your Keycloak
add the desired applications (or other Clients) to the Client Scope(s). Those you want to authorize transitively from this Client.
authenticate against this Client with Client Credentials flow (given the token endpoint, client id, credentials, scope)
ensure that you are authenticating through TLS and that parameters are included in request body (and not in headers - for enhanced privacy)
further harden security of your Client(s)
When you do not want anymore this particular server (client?) application to access your applications, you can change the corresponding "authentication" Client's secret/credentials or simply delete it.
"I don't think giving my client secret to all my "customers" is the proper way to do it."
You are right and the proposed method above strictly avoids that. Each customer would have its own credentials.
EDIT
(adding more details)
By performing as above, you would end up with the following scheme:
Flow Keycloak Server
C/S app. or Customer X <--- Client Creds ---> Auth. Client X
--- Access Token ---> Appl. Client <--> Appl. Server
C/S app. or Customer Y <--- Client Creds ---> Auth. Client Y
--- Access Token ---> Appl. Client <--> Appl. Server
Browser users <--- Standard ------> Appl. Client <--> Appl. Server
Note: this is not a detailed flow chart. Arrows mostly show relationships here.
Finally, please note that the terminology may differ a little here, but the proposed method is basically the same that Google uses. So you may aswell take some inpiration from there:
https://developers.google.com/identity/protocols/oauth2
I just had the same problem some weeks ago
In my case, I have a backend API and a frontend application that the users can use.
Eventually, I can't share the client_secret to the frontend application.
So here is my solution:
On keycloak, create a client (ex front_end_client) with grant type public
This client is going to be used by the frontend application to authenticate users using implicit flow (with PKCE will be more secure)
On keycloak, create a second client (On the same REALM as the first client) with grant type confidential, this client is going to be used by the backend API
Now, this is how it works:
Frontend app authenticate users and get the access token (Using the font_end_client)
The frontend app sends this token for every request to the backend
Backend app verify this token, and can retrieve permissions from it

Do I need account-based permissions to initialize an mssoap client from a wsdl file?

I'm getting the this error when I try to use an ASP.NET WebService through an MSSOAP Client:
"WSDL Reader: Loading of the WSDL file failed HRESULT=0X80040154 Class not registered - Client: An
unanticipated error occured during the processing of this request.HRESULT=0x1812040:Class not registered."
At first I thought the SOAP library was not properly registered. But when I debugged the code I realized the error was being raised at the time of reading the web service definition (The Soap client does get created).
SOAPClient.mssoapinit "wsdl_URL"
Now, the issue only occurs when I execute the code as certain account (as for the rest of the accounts the code works pretty well). The original client is a Classic ASP page but I've reproduced the problem using a vbs script.
I run the script under several accounts, but just one presents the wsdl-reading failure.
I've granted reading permissions to the directory that contains the
asmx file to the failing account.
I've changed the physical path of the virtual directory where the
webservice is hosted to a general non-particular-profile location
like C:.
Ironically the application pool identity of the web application is
the account that presents the failure.
All the accounts can read the wsdl file through a browser just typing
the url (but still one of them can't from client code)
Do I need to grant additional permissions for the account in order to read the web service definition and initialize the soap client?

WSO2 ESB-4.8.1 connecting to WSO2-5.0.0 IS and UserInformationRecoveryService?wsdl

I am trying to connect WSO2 Identity Server to the WSO2 ESB. I have installed both products to my local computer and have configured them to run simultaneously. WSO2-IS has an offset of 1 and I set hostnameverifier to AllowAll. Given that both are on my local machine, I did not see the need to adjust or set anything in the Keystore. In WSO2-IS I have exposed the admin-wsdl's.
What I am trying to do is create an endpoint wsdl that points to
https://localhost:9444/services/UserInformationRecoveryService?wsdl (which is in the WSO2-IS).
In the admin console, I add the endpoint with the variables
1. The Name is UserInformationRecoveryService
2. The URI is https://localhost:9444/services/UserInformationRecoveryService?wsdl
3. The Service is UserInformationRecoveryService
4. The port is 9444 (which is the offset from 9443)
When I test this service, it says it is valid. When I add it, it disappears and I get the errors:
[2015-01-16 17:59:20,923] ERROR - WSDL11EndpointBuilder Couldn't retrieve endpoint information from the WSDL.
[2015-01-16 17:59:20,924] ERROR - WSDLEndpointFactory Couldn't create endpoint from the given WSDL URI : Couldn't retrieve endpoint information from the WSDL.
org.apache.synapse.SynapseException: Couldn't retrieve endpoint information from the WSDL.
at org.apache.synapse.config.xml.endpoints.utils.WSDL11EndpointBuilder.handleException(WSDL11EndpointBuilder.java:199)
... (I removed many of the other at's)
I also tried adding it as a wsdl proxy, but receive the error
Couldn't create endpoint from the given WSDL URI : Couldn't retrieve endpoint information from the WSDL.
and the errors:
[2015-01-16 18:06:49,890] ERROR - ProxyServiceAdminClient Couldn't create endpoint from the given WSDL URI : Couldn't retrieve endpoint information from the WSDL.
org.wso2.carbon.proxyadmin.stub.ProxyServiceAdminProxyAdminException: Couldn't create endpoint from the given WSDL URI : Couldn't retrieve endpoint information from the WSDL.
at org.wso2.carbon.proxyadmin.ui.client.ProxyServiceAdminClient.addProxy(ProxyServiceAdminClient.java:105)
at org.apache.jsp.proxyservices.template_005fwsdl_002dbased_jsp._jspService(org.apache.jsp.proxyservices.template_005fwsdl_002dbased_jsp:343)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:111)
I am relatively new to the WSO2 suite, and have been unable to find many discussions on these two products working together.
From what I have read, WSO2-IS uses SOAP. The client that we are developing will be using REST. The ESB is to connect the client to WSO2-IS and convert SOAP-TO-REST.
My question is
1. Why do I receive these errors?
2. What is the best practice to connect the two services.
Thank you.
Enable option in carbon.xml and try your wsdl link in a browser and see whether you can access it or not.(All admin services's wsdls are hided) Later try to create proxy.
After more reading, I found that I was using the wrong port name. I was assuming the port was 9444, but having reread the wsdl again, I found that the ports were called
wsdl:port name="UserInformationRecoveryServiceHttpsSoap11Endpoint"
wsdl:port name="UserInformationRecoveryServiceHttpsSoap12Endpoint"
wsdl:port name="UserInformationRecoveryServiceHttpsEndpoint"

JMeter test with CAS not redirect to service

I am doing a jmeter test with CAS , but encountered a problem.
I got it logged in succesfully with full of CAS parameters(username/password/lt/service/_eventId), but the response data was not my page specified in the parameter "service".
It is not redirected.
Why? Does anyone know this issue?
I admit that I am not so familiar with CAS...
After reading the protocol of CAS, I find this:
(from http://www.jasig.org/cas/protocol)
2.2.4. response
One of the following responses MUST be provided by /login when it is operating as a credential acceptor.
successful login: redirect the client to the URL specified by the "service" parameter in a manner that will not cause the client's credentials to be forwarded to the service. This redirection MUST result in the client issuing a GET request to the service. The request MUST include a valid service ticket, passed as the HTTP request parameter, "ticket". See Appendix B for more information. If "service" was not specified, CAS MUST display a message notifying the client that it has successfully initiated a single sign-on session.
So ,I add a new request using GET with two parameters:service, ticket(its value is the same with lt).
Then the script run successfully and finally redirected..