Identity propagation in wildfly elytron with HTTP bearer authentication - wildfly

We use a elytron/token-realm with a elytron/http-authentication-factory and the BEARER_TOKEN mechanism to authenticate users. The system consists of two applications, running in separate wildfly instances. One application remotely invokes EJBs of the other application. We would like the identity of the current user to be propagated over the remote EJB call.
I am trying to set up Identity propagation according to the JBoss documentation.
BEARER_TOKEN is listed as a supported mechanism. The ejb system is configured to use the new HTTP transport (call target is http://server:port/wildfly-services), instead of the remote+http protocol.
I would expect the bearer token to be added as an HTTP “Authorization: Bearer” header by the forwarding server, when making the ejb call to the receiving server, however this does not happen and the HTTP response is 401.
This is the configuration of the forwarding server:
/subsystem=ejb3/application-security-domain=other:write-attribute(name=security-domain,value=ApplicationDomain)
/subsystem=elytron/authentication-configuration=remote-ejb-configuration:add(security-domain=ApplicationDomain)
/subsystem=elytron/authentication-context=remote-ejb-context:add(match-rules=[{authentication-configuration=remote-ejb-configuration}])
/socket-binding-group=standard-sockets/remote-destination-outbound-socket-binding=remote-partner-ejb/:add(host="server",port="8080")
/subsystem=remoting/remote-outbound-connection=remote-ejb:add(outbound-socket-binding-ref=remote-partner-ejb, authentication-context=remote-ejb-context)
/subsystem=undertow/server=default-server/host=default-host/setting=http-invoker:undefine-attribute(name=security-realm)
/subsystem=undertow/server=default-server/host=default-host/setting=http-invoker:write-attribute(name=http-authentication-factory, value=jwt-http-authentication)
And here is the error seen on the forwarding server side:
Caused by: javax.naming.AuthenticationException: WFHTTP000013: Authentication failed (full response ClientResponse{responseHeaders={Connection=[keep-alive], WWW-Authenticate=[Bearer realm="jwt-realm"], Set-Cookie=[JSESSIONID=0BAxZeBpW-RuStmtGFylfbYBpypUJYsqLMlsrw04.partner-as-76d77b7f5c-6bcb6; path=/wildfly-services], Server=[nginx/1.23.3], Content-Type=[text/html], Content-Length=[77], Date=[Mon, 09 Jan 2023 10:34:00 GMT]}, responseCode=401, status='Unauthorized', protocol=HTTP/1.1})
There is a quickstart showing identity propagation, but it uses SASL authentication, which does not support BEARER_TOKEN mechanism
Has anyone had luck with a setup like this?

Related

Oracle Service Bus error: ClassCastException: CountingRequestWrapper cannot be cast to ServletRequestImpl

I developed a service for Oracle Service Bus and deployed on a WebLogic 12c server. The proxy service uses an HTTP adapter so that the service can be called using SOAP. The business service uses a REST adapter.
The service works fine when I test it on the integrated server or on my UAT server (which is WebLogic 12c) using the test page that's invoked from the ServiceBus console. Also tried using SOAPUI tool on two different Windows PC's.
However, when the third party invokes my service, I get an exception in my log. I added alerts and logs in my pipeline but neither of them get invoked meaning the exception happens in WebLogic before it can pass the request to my adapter.
Googling for "CountingRequestWrapper" gives zero results. I really can't figure out what is causing this.
Here's the log:
module:/MyApp/MyService path:null spec-version:3.1], request: weblogic.servlet.internal.ServletRequestImpl#35881271[
GET /MyApp/MyService?wsdl HTTP/1.1
Content-Type: text/xml;charset="utf-8"
Accept: /
Connection: Keep-Alive
]] Root cause of ServletException.
java.lang.ClassCastException: com.bea.wli.sb.transports.http.wls.CountingRequestWrapper cannot be cast to weblogic.servlet.internal.ServletRequestImpl
at com.bea.wli.sb.transports.http.wls.HttpTransportServlet.service(HttpTransportServlet.java:121)
at weblogic.servlet.FutureResponseServlet.service(FutureResponseServlet.java:24)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:295)
at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:260)
at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:137)
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:353)
at weblogic.servlet.internal.TailFilter.doFilter(TailFilter.java:25)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:78)
I did notice that at the top it says: path: null. Could it be something to do with that?
Request from log looks like a GET to wsdl address (GET /MyApp/MyService?wsdl) and you mentioned it's a soap proxy so that should most likely be a POST to service endpoint address. I would suggest to check 3rd party client side configuration first.

While connecting two app servers with an ibm http webserver, we are able to successfully connect with only one server

While running two app servers (which has mobilefirst servers hosted 7.1 version) from ibm http server, only one server runs successfully on keeping only one of the Route attribute active in the plugin-cfg.xml of the http server. In the server which is not running, the following error is seen in the messages.log.
CWWKS4001E: The security token cannot be validated. This can be for the following reasons
1. The security token was generated on another server using different keys.
2. The token configuration or the security keys of the token service which created the token has been changed.
3. The token service which created the token is no longer available.
Kindly guide in resolving the error above.
Thanks.
Sounds like your two servers have not exchanged/shared LTPA keys and IHS and the WAS Plugin are a red herring.
http://www.ibm.com/support/knowledgecenter/SSAW57_liberty/com.ibm.websphere.wlp.nd.doc/ae/twlp_sec_ltpa.html
http://www.ibm.com/support/knowledgecenter/SSAW57_liberty/com.ibm.websphere.wlp.nd.doc/ae/twlp_sec_sso.html
Note: For SSO to work across Liberty servers, full profile servers, or both, set the following resources:
The servers must use the same LTPA keys and share the same user registry.
Sounds like communication issue between two servers. Are the inbound ports opened on another server to communicate with HTTP server? if they are opened use telnet and test whether both servers (HTTP and app server) are communicating with each other.
On HTTP Server, open command prompt and enter below command.
telnet <app server ip> <app server port>
If this is not successful then you need to open ports on app server.

Behaviour of SAML when HTTP Server used for high availability

I have implemented the supporting of SAML SSO to have my application act as the Service Provider using Spring Security SAML Extension. I was able to integrate my SP with different IDPs. So for example I have HostA,HostB, and HostC, all these have different instances of my application. I had an SP metadata file specified for each host and set the AssertionConsumerServiceURL with the URL of that host( EX:https:HostA.com/myapp/saml/sso ). I added each metadata file to the IDP and tested all of them and it is working fine.
However, my project also supports High Availability by having an IBM HTTP Server configured for load balancing. So in this case the HTTP Server will configure the hosts(A,B,C) to be the hosts used for load balancing, the user will access the my application using the URL of the HTTP server: https:httpserver.com/myapp/
If I defined one SP metadata file and had the URL of the HTTP Server specified in the AssertionConsumerServiceURL( https://httpserver.com/saml/sso ) and changed my implementation to accept assertions targeted to my HTTP Server, what will be the outcome of this scenario:
User accesses the HTTPServer which dispatched the user to HostA(behind the scenes)
My SP application in HostA sends a request to the IDP for authentication.
The IDP sends back the response to my httpserver as: https://httpserver.com/saml/sso .
Will the HTTP Server redirect to HostA, to have it like this: https://HostA.com/saml/sso
Thanks.
When deploying same instance of application in a clustered mode behind a load balancer you need to instruct the back-end applications about the public URL on the HTTP server (https://httpserver.com/myapp/) which they are deployed behind. You can do this using the SAMLContextProviderLB (see more in the manual). But you seem to have already successfully performed this step.
Once your HTTP Server receives a request, it will forward it to one of your hosts to URL e.g. https://HostA.com/saml/sso and usually will also provide the original URL as an HTTP header. The SAMLContextProviderLB will make the SP application think that the real URL was https://httpserver.com/saml/sso which will make it pass all the SAML security checks related to destination URL.
As the back-end applications store state in their HttpSessions make sure to do one of the following:
enable sticky session on the HTTP server (so that related requests are always directed to the same server
make sure to replicate HTTP session across your cluster
disable checking of response ID by including bean EmptyStorageFactory in your Spring configuration (this option also makes Single Logout unavailable)

Intercepting and forwarding client certificate to webservice

I have a web application (gwt) that is running on a tomcat application server. This web application consumes several web services (login, application data transfer, queries, etc.). The web service client on the tomcat is implemented as apache axis2 web service client.
For user log on I provide a form in the web application with username and password. This data are transmitted via web service to authenticate the user.
It is planned to change the hole authentication mechanism to client certificated based authentication. The authentication still should be done on the web service provider side.
So my system has three relevant components: the web client, the tomcat application server and the web service provider.
Every user of the application has its own private client certificate (PKI Token, X.509- Auth-Cert). When the user connects to the web application his certificate is requested.
How can I forward the client certificates for use in the web services? (The tomcat will not be responsible for authentication).
1.) Is there a way to intercept the request and extract the client certificates before authentication error occurred?
I found some information about Servlet Filters what sounds really good, but I’m not sure where to implement it to intercept the certificates before they are verified against tomcats keystore.
2.) If it is possible, how can I pass after the client certificate to the web service?
Thank you for reading
No, not really. The real piece used in authentication is the private key associated with the certificate, not just the certificate itself. And, typically, you have no way of retrieving that from the web client. Therefore, you cannot really pass-through the credentials you receive from a web client on to the web service client. The certificate itself is readily available, but is useless for authentication without the corresponding private key.

How can I trust that the SiteMinder HTTP headers haven't been tampered with?

I am completely new to SiteMinder and SSO in general. I poked around on SO and CA's web site all afternoon for a basic example and can't find one. I don't care about setting up or programming SM or anything like that. All of that is already done by someone else. I just want to adapt my JS web app to use SM for authentication.
I get that SM will add a HTTP header with a key such as SM_USER that will tell me who the user is. What I don't get is -- what prevents anyone from adding this header themselves and bypassing SM entirely? What do I have to put in my server-side code to verify that the SM_USER really came from SM? I suppose secure cookies are involved...
The SM Web Agent installed on the Web Server is designed to intercept all traffic and checks to see if the resource request is...
Protected by SiteMinder
If the User has a valid SMSESSION (i.e. is Authenticated)
If 1 and 2 are true, then the WA checks the Siteminder Policy Server to see if the user is Authorized to access the requested resource.
To ensure that you don't have HTTP Header injections of user info, the SiteMinder WebAgent will rewrite all the SiteMinder specific HTTP Header information. Essentially, this means you can "trust" the SM_ info the WebAgent is presenting about the user since it is created by the Web Agent on the server and not part of the incoming request.
Because all traffic should pass through Siteminder Web Agent so even if the user sets this header it will be overwritten/removed
All Siteminder architectures do indeed make the assumption that the application just has to trust the "SM_" headers.
In practice, this may not be sufficient depending on the architecture of your application.
Basically, you have 3 cases:
The Web Agent is installed on the web server where your application runs (typical case for Apache/PHP applications): as stated above, you can trust the headers as no requests can reach your application without being filtered by the web agent.
The Web Agent is installed on a different web server than the one where your application runs, but on the same machine (typical case: SM Agent installed on an Apache front-end serving a JEE Application Server): you must ensure that no requests can directly reach your application server. Either you bind your application server to the loopback interface or you filter the ports on the server.
The Web Agent runs on a reverse proxy in front of your application. Same remark. The only solution here is to implement an IP filter on your application to only allow requests that come from your reverse proxy.
SiteMinder r12.52 contains a new functionality named Enhanced Session Assurance with DeviceDNA™. DeviceDNA can be used to ensure that the SiteMinder Session Cookie has not been tampered with. If the Session is replayed on a different machine, or from another brower instance on the same machine, DeviceDNA will catch this and block the request.
Click here to view a webcast discussing new features in CA SiteMinder r12.52
Typical enterprise architecture will be Webserver (Siteminder Agent) + AppServer (Applications)
Say IP filtering is not enabled, and webs requests are allowed directly to AppServer, bypassing webserver and the sso-agent.
If applications have to implement a solution to assert the request headers / cookies are not tampered / injected, do we have any solution simillar to the following?
Send the SM_USERID encrypted in a seperate cookie or encrypted (Sym/Asym) along with SMSESSION id
Application will use the key to decrypt the SMSESSION or SM_USERID to retrive the user id, session expiry status and any other addtional details and authorization details if applicable.
Application now trusts the user_id and do authentication