CAS integration with IdentityServer3 (as an Open Id Connect client) - java

I'm trying to integrate CAS server with IdentityServer3 (CAS acting as a Open ID Client).
Following the guides, I updated the cas.properties and changed the following:
```
cas.pac4j.oidc.id=clientid
cas.pac4j.oidc.secret=secret
cas.pac4j.oidc.discoveryUri=https://IdentityServer3/.well-known/openid-configuration
```
I also update the pom.xml file and added pac4j-oidc dependency (not sure if it was needed but it was missing initially)
Now when I access the CAS login page I can see the Oidc long link but the URL is invalid:
https://localhost:8433/cas/login?client_name=OidcClient&needs_client_redirection=true
I was expecting to automatically discover the IdentityServer URL from the discovery document. Is there anything else I need to do?
I also tried adding the following bean to the pac4jContext.xml file:
```
<bean id="oidc1" class="org.pac4j.oidc.client.OidcClient">
<property name="id" value="clientid" />
<property name="secret" value="secret" />
<property name="discoveryUri" value="https://IdentityServer3/.well-known/openid-configuration" />
</bean>
```
When I do this the CAS server is not working anymore (I get a 404 when trying to access it via Tomcat)
Java is not my first language so I'm not sure if I'm missing something obvious but I would really appreciate some help with this.

Related

Kie Server points to non Web Socket controller

After integrating LDAP Authentication in jBPM, I am getting this error when I access Manage from jbpm-console:
Attention
Execution Server Unavailable
There is currently no server connected.
on console I am constantly getting this error:
19:35:09,678 INFO [org.kie.server.controller.websocket.client.WebSocketKieServerControllerImpl] (KieServer-ControllerConnect) Kie Server points to non Web Socket controller 'http://localhost:8080/jbpm-console/rest/controller', using default REST mechanism
19:35:10,501 WARN [org.kie.server.services.impl.controller.DefaultRestControllerImpl] (KieServer-ControllerConnect) Exception encountered while syncing with controller at http://localhost:8080/jbpm-console/rest/controller/server/sample-server error Error while sending PUT request to http://localhost:8080/jbpm-console/rest/controller/server/sample-server response code 405
When I comment out LDAP login-module from standalone.xml, it works, but not with LDAP Enabled.
Versions used:
kie-server-7.29.0.Final-wildfly-14.0.1.Final
jbpm-console-7.29.0.Final-wildfly-14.0.1.Final
jbpm-casemgmt-7.29.0.Final-wildfly-14.0.1.Final
Used jbpm-installer-7.29.0.Final to build and start the Wildfly server.
For access to KIE Execution Server you need to have user with role 'kie-server'. I had same case. Adding user 'kieserver' with role 'kie-server'
solved my problem. Documentation of KIE Execution Server https://docs.jboss.org/drools/release/6.2.0.Final/drools-docs/html/ch19.html
org.kie.workbench.controller: The URL used to connect to the jBPM
controller, for example,
ws://localhost:8080/kie-server-controller/websocket/controller.
org.kie.workbench.controller.user: The jBPM controller user. Default
value: kieserver.
org.kie.workbench.controller.pwd: The jBPM controller password.
Default value: kieserver1!.
I got the same error when trying to configure jbpm to use DB authentication:
Exception encountered while syncing with controller at http://localhost:8080/business-central/rest/controller/server/sample-server error Error while sending PUT request to http://.... response code 405
The jbpm version that i'm using is: jbpm-server-7.47.0.Final-dist.zip (released at Dec 4, 2020)
In the DB, i have already setup user "admin" with password "admin" that contains the "kie-server" role.
And in the standalone.xml, i also added following system properties to define the user name and password to connect to the kie server and controller:
<property name="org.kie.server.user" value="admin"/>
<property name="org.kie.server.pwd" value="admin"/>
<property name="org.kie.server.controller.user" value="admin"/>
<property name="org.kie.server.controller.pwd" value="admin"/>
Even though startup the server with the mentioned error, the kie server can startup successfully. I tried to use the 'admin' user to access the kie-server REST API (e.g. GET http://localhost:8080/kie-server/services/rest/server) without any problem. I also tried to login to the business central with the 'admin' user and also successful.
But the problem still remain the same that there is no server available for kjar deployment.
Resolution
It took me several days to figure out that its the configuration issue in the standalone.xml file.
In the standalone.xml, there are by default provided a set of system properties with name is "kie.keystore.key.*". These attributes are used to retrieve the password value from the a keystore file (e.g. jBPMKeystore.jceks in the configuration folder). By checking the source code of DefaultRestControllerImpl.java, the logic is to first load the password from the keystore file and if there is problem, it will then retrieve the password from the system property: org.kie.server.controller.pwd
So, what we need to do is to comment out / remove the system properties "kie.keystore.*" inside the <system-properties> tag:
<!--
<property name="kie.keystore.keyStoreURL" value="file:///${jboss.server.config.dir}/jBPMKeystore.jceks"/>
<property name="kie.keystore.keyStorePwd" value="jBPMKeyStorePassword"/>
<property name="kie.keystore.key.server.alias" value="jBPMAlias"/>
<property name="kie.keystore.key.server.pwd" value="jBPMKeyPassword"/>
<property name="kie.keystore.key.ctrl.alias" value="jBPMAlias"/>
<property name="kie.keystore.key.ctrl.pwd" value="jBPMKeyPassword"/>
-->

How can I get spring security to work behind a load balancer across multiple domains?

We are moving an old java / spring app into AWS, so it is behind an AWS Application Load Balancer. Tomcat is running directly behind the load balancers on port 8080, and we are using HTTP between the load balancer and tomcat.
The problem is under this scenario the spring security module doesn't recognize that the connection is secure.
I can resolve this issue by configuring the Connection:
<Connector port="8080"
protocol="HTTP/1.1"
connectionTimeout="20000"
proxyName="single-host.example.com"
secure="true"
scheme="https"
redirectPort="443"
proxyPort="443" />
Which works for a single host name. However, I need this to work across multiple host names.
I have tried skipping the proxy and adding:
server.tomcat.remote_ip_header=X-Forwarded-For
server.tomcat.protocol_header=X-Forwarded-Proto
But this doesn't seem to make any difference.
Is there a way to support multiple hostnames in this scenario?
AWS LoadBalancer sends X-Forwarded-Proto header when proxying request.
On Tomcat configure RemoteIpValve to have request.secure and other request variable interpreted from those headers.
<Valve className="org.apache.catalina.valves.RemoteIpValve"/>
You should also omit setting proxyName on Connector conifiguration since it should come automatically from valve.
I am got some solution procedure. So I have provided 2 suggestion. First one is step by step pictorial view to solve your issue. If not, then go to the second one.
Second one is using X-Forwarded-Proto and related configuration to solve the issue. Hope it will help you.
Suggestion#1:
Amazon cloud environment with load balance support process is pretty straight-forward. A step by step tutorial is given here:Elastic Load Balancing (ELB) with a Java Web Application + Tomcat + Session Stickiness
Suggestion#2:
phillipuniverse has given a solution.
Configuring the following valve in Tomcat will make request.isSecure() function properly with the X-Forwarded-Proto header:
<Valve className="org.apache.catalina.valves.RemoteIpValve" protocolHeader="X-Forwarded-Proto" />
This can be added to Tomcat's server.xml under the <Host> element.
And of course, after all that, there is a very, VERY simple solution that fixes this problem from the very beginning. All that really needed to happen was to modify the proto channel filters from this:
if ("https".equals(invocation.getHttpRequest().getHeader("X-Forwarded-Proto"))) {
getEntryPoint().commence(invocation.getRequest(), invocation.getResponse());
}
to:
if (invocation.getHttpRequest().isSecure() ||
"https".equals(invocation.getHttpRequest().getHeader("X-Forwarded-Proto"))) {
getEntryPoint().commence(invocation.getRequest(), invocation.getResponse());
}
The final configuration here should be this:
<bean class="org.broadleafcommerce.common.security.channel.ProtoChannelBeanPostProcessor">
<property name="channelProcessorOverrides">
<list>
<bean class="org.broadleafcommerce.common.security.channel.ProtoInsecureChannelProcessor" />
<bean class="org.broadleafcommerce.common.security.channel.ProtoSecureChannelProcessor" />
</list>
</property>
</bean>
After that,
Some prefer to terminate SSL at the load balancer, and to not use Apache web server. In that case, you often accept traffic at the LB on 80 / 443, and then route traffic to Tomcat on 8080.
If you are using Spring's port mapping:
<sec:port-mappings>
<sec:port-mapping http="8080" https="443"/>
</sec:port-mappings>
This will not work as it does not override the port mapping in the new Channel Processors. Here is a configuration that will work, though:
<bean class="org.broadleafcommerce.common.security.channel.ProtoChannelBeanPostProcessor">
<property name="channelProcessorOverrides">
<list>
<bean class="org.broadleafcommerce.common.security.channel.ProtoInsecureChannelProcessor" >
<property name="entryPoint">
<bean class="org.springframework.security.web.access.channel.RetryWithHttpEntryPoint">
<property name="portMapper" ref="portMapper"/>
</bean>
</property>
</bean>
<bean class="org.broadleafcommerce.common.security.channel.ProtoSecureChannelProcessor" >
<property name="entryPoint">
<bean class="org.springframework.security.web.access.channel.RetryWithHttpsEntryPoint">
<property name="portMapper" ref="portMapper"/>
</bean>
</property>
</bean>
</list>
</property>
</bean>
Resource Link: HTTPS/SSL/Spring Security doesn't work in both a load balancer and non-load balancer environment #424
You should setup HTTPS connection on the LB, then you'll have a proper TLS connection between the LB and the tomcat so spring will stop crying. You'll just have to provide a self-signed certificate to the LB and setup your spring security module with the private key that have generated this self signed certificate.
(a more complex option: setup properly the tomcat proxy, to force it to encapsulate the HTTP stream of the LB in an HTTPS stream. Setup all TLS requirements in the proxy: certificate, private key...)
Did you try to put LB address as proxyName? It might work on your case.

HTTP Proxy Setup For Java JVM

Setting up an HTTP proxy for Java JVM 6.x isn't working for me; I'm hoping someone can spot what I'm missing.
I have a Java application deployed on JBOSS 5.1.2 that makes several calls to external web services. I'd like to be able to intercept these calls using a proxy: Fiddler version 4.4.8.0.
After doing an SO search I added the following flags to my JBOSS VM parameters at startup:
-DproxySet=true -Dhttp.proxyHost=localhost -Dhttp.proxyPort=8888 -Dhttps.proxyHost=localhost -Dhttps.proxyPort=8888
I'm running JBOSS in IntelliJ 14.
I can see traffic from the browser to the application if I start JBOSS, Fiddler, and open the UI in Chrome. I do not see any calls from JBOSS to external services being intercepted. I thought I would see all the calls from JBOSS to external services in addition to those from the browser to JBOSS.
Update:
I tried adding these to properties-service.xml per this SO answer - no joy.
I'm running Spring 3, using Apache HttpClient as my web service client. I'm going to look into configuring proxy just for it.
Thanks to bmargulies and anyone else who looked at this. I have a solution that I hope will help someone else.
Adding -Dhttp.proxyHost parameters to my JVM startup options did nothing.
Adding those same parameters to JBOSS 5.1.2 configuration in my deployment properties-services.xml did nothing.
I believe that using Spring 3.x is a factor in explaining this behavior. I had to tell the Spring web service clients to use a proxy.
I added some Spring beans to wire in a Fiddler proxy HttpClient and injected that into the web service client, replacing the non-proxied version.
It failed the first time I tried it. It took me a while to figure out that the Apache Commons HttpConfiguration class didn’t follow the Java bean standard, so Spring blew up when it tried to wire it. I had to use the Spring MethodInvokingFactoryBean to get around it.
Here's the pertinent Spring configuration XML:
<!-- New beans for Fiddler proxy -->
<bean id="fiddlerProxyHost" class="org.apache.commons.httpclient.ProxyHost">
<constructor-arg name="hostname" value="localhost"/>
<constructor-arg name="port" value="8888"/>
</bean>
<bean id="fiddlerProxyHostConfiguration" class="org.apache.commons.httpclient.HostConfiguration"/>
<bean id="fiddlerProxyHostSetter" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject" ref="fiddlerProxyHostConfiguration"/>
<property name="targetMethod" value="setProxyHost"/>
<property name="arguments" ref="fiddlerProxyHost"/>
</bean>
<bean id="fiddlerProxyClient" class="org.apache.commons.httpclient.HttpClient">
<property name="hostConfiguration" ref="fiddlerProxyHostConfiguration"/>
</bean>
Now I can see the calls from the application to the web service in Fiddler. Joy!
Those parameters, first and foremost, are read by HttpURLConnection. They are specific to HTTP, of course, and so any other means of connecting to the outside world will necessarily ignore them.
There are many good reasons for code to avoid HttpURLConnection and just open a TCP connection through a plain old socket, even if that code plans to talk HTTP. HttpURLConnection has several 'browser emulation features' that get in the way. For example, it's broken for CORS and rejects some legitimate HTTP verbs.
Code that does that and in turn happens to do HTTP might choose to respect those parameters, and it might not. For example, I'm reasonably sure that the Apache Commons HTTP library gives the caller a choice.
If you put JBoss in a debugger and break on the socket connection primitives, I think you'll find out what's happening to you pretty quick in this respect.

service properties in CAS client

I wanted to connect one of my web apps with CAS server. I successfully created my CAS server also with SSL setting. but there is an ambiguity when I wanted to set up my CAS client.
In spring web site there is a bean like this which they say we should initialize and create it.
<bean id="serviceProperties" class="org.springframework.security.cas.ServiceProperties">
<property name="service" value="https://localhost:8443/cas-sample/j_spring_cas_security_check" />
<property name="sendRenew" value="false" />
</bean>
The problem here I can't understand what is "service" and what URL it is referred to? I mean in my web app, what the value of "service" should be?
From the Spring Security 3 book:
The service property indicates to CAS the service to which the user will be
authenticated.
For example: https://localhost:8443/your-web-application/j_spring_cas_security_check

How to write Java code to Spring Configuration File

I have a spring configuration file for spring security. At beginning my file is getting from cache and when I do an operation it redirects me to the login page (However I can see page at first.) I want to solve that cache problem like that:
<beans:property name="defaultTargetUrl" value="/index.html?Math.random()"/>
However I think that it is not doing what I want, I am not sure.
Any ideas?
Try using Spring expression language
<property name="url" value="#{'/index.html?' + T(java.lang.Math).random()}"/>

Categories

Resources