Difference between 2-way SSL and single authentication in Artemis - ssl

I have Artemis setup with 3 brokers (1-master and 2-slaves) and would like to use SSL between them and client. RIght now I'm using self signed certificates which were generated like this
# Create a broker key and cert - import the keypair and cert into the broker keystore
openssl req -newkey rsa:2048 -nodes -keyout broker_keypair.pem -x509 -days 65000 -out broker_cert.pem
openssl pkcs12 -inkey broker_keypair.pem -in broker_cert.pem -export -out broker_ks.p12
# Create a client key and cert - import the keypair and cert into the client keystore
openssl req -newkey rsa:2048 -nodes -keyout client_keypair.pem -x509 -days 65000 -out client_cert.pem
openssl pkcs12 -inkey client_keypair.pem -in client_cert.pem -export -out client_ks.p12
# Create a truststore for the broker, and import the client's certificate. This establishes that the broker "trusts" the client:
keytool -import -alias client -keystore broker_ts.p12 -file client_cert.pem -deststoretype pkcs12
# Create a truststore for the client, and import the broker's certificate. This establishes that the client "trusts" the broker:
keytool -import -alias broker -keystore client_ts.p12 -file broker_cert.pem -deststoretype pkcs12
my broker.xml for master:
<?xml version='1.0'?>
<configuration xmlns="urn:activemq"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xi="http://www.w3.org/2001/XInclude"
xsi:schemaLocation="urn:activemq /schema/artemis-configuration.xsd">
<core xmlns="urn:activemq:core" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:activemq:core ">
<name>0.0.0.0</name>
<persistence-enabled>true</persistence-enabled>
<journal-type>ASYNCIO</journal-type>
<paging-directory>data/paging</paging-directory>
<bindings-directory>data/bindings</bindings-directory>
<journal-directory>data/journal</journal-directory>
<large-messages-directory>data/large-messages</large-messages-directory>
<journal-datasync>true</journal-datasync>
<journal-min-files>2</journal-min-files>
<journal-pool-files>10</journal-pool-files>
<journal-device-block-size>4096</journal-device-block-size>
<journal-file-size>10M</journal-file-size>
<journal-buffer-timeout>28000</journal-buffer-timeout>
<journal-max-io>4096</journal-max-io>
<disk-scan-period>5000</disk-scan-period>
<max-disk-usage>100</max-disk-usage>
<critical-analyzer>true</critical-analyzer>
<critical-analyzer-timeout>120000</critical-analyzer-timeout>
<critical-analyzer-check-period>60000</critical-analyzer-check-period>
<critical-analyzer-policy>HALT</critical-analyzer-policy>
<page-sync-timeout>1628000</page-sync-timeout>
<global-max-size>204Mb</global-max-size>
<connectors>
<connector name="netty-connector">tcp://amq1:61616?sslEnabled=true;keyStorePath=client_ks.p12;keyStorePassword=artemis;trustStorePath=client_ts.p12;trustStorePassword=artemis</connector>
</connectors>
<acceptors>
<acceptor name="netty-acceptor">tcp://amq1:61616?sslEnabled=true;keyStorePath=broker_ks.p12;keyStorePassword=artemis;trustStorePath=broker_ts.p12;trustStorePassword=artemis;needClientAuth=true</acceptor>
</acceptors>
<cluster-connections>
<cluster-connection name="my-cluster">
<address>amq</address>
<connector-ref>netty-connector</connector-ref>
<retry-interval>1000</retry-interval>
<retry-interval-multiplier>3</retry-interval-multiplier>
<use-duplicate-detection>true</use-duplicate-detection>
<message-load-balancing>STRICT</message-load-balancing>
<discovery-group-ref discovery-group-name="my-discovery-group"/>
</cluster-connection>
</cluster-connections>
<broadcast-groups>
<broadcast-group name="my-broadcast-group">
<local-bind-address>amq1</local-bind-address>
<local-bind-port>9876</local-bind-port>
<group-address>231.7.7.7</group-address>
<group-port>9876</group-port>
<broadcast-period>2000</broadcast-period>
<connector-ref>netty-connector</connector-ref>
</broadcast-group>
</broadcast-groups>
<discovery-groups>
<discovery-group name="my-discovery-group">
<local-bind-address>amq1</local-bind-address>
<local-bind-port>9876</local-bind-port>
<group-address>231.7.7.7</group-address>
<group-port>9876</group-port>
<refresh-timeout>10000</refresh-timeout>
</discovery-group>
</discovery-groups>
<network-check-list>amq1,amq2,amq3</network-check-list>
<network-check-period>5000</network-check-period>
<network-check-timeout>1000</network-check-timeout>
<network-check-ping-command>ping -c 1 -t %d %s</network-check-ping-command>
<network-check-ping6-command>ping6 -c 1 %2$s</network-check-ping6-command>
<!-- Other config -->
<ha-policy>
<replication>
<master>
<check-for-live-server>true</check-for-live-server>
</master>
</replication>
</ha-policy>
<security-settings>
<security-setting match="#">
<permission type="createNonDurableQueue" roles="amq"/>
<permission type="deleteNonDurableQueue" roles="amq"/>
<permission type="createDurableQueue" roles="amq"/>
<permission type="deleteDurableQueue" roles="amq"/>
<permission type="createAddress" roles="amq"/>
<permission type="deleteAddress" roles="amq"/>
<permission type="consume" roles="amq"/>
<permission type="browse" roles="amq"/>
<permission type="send" roles="amq"/>
<!-- we need this otherwise ./artemis data imp wouldn't work -->
<permission type="manage" roles="amq"/>
</security-setting>
</security-settings>
<addresses>
<address name="exampleQueue">
<anycast>
<queue name="exampleQueue"/>
</anycast>
</address>
<address name="DLQ">
<anycast>
<queue name="DLQ" />
</anycast>
</address>
<address name="ExpiryQueue">
<anycast>
<queue name="ExpiryQueue" />
</anycast>
</address>
</addresses>
<address-settings>
<!-- if you define auto-create on certain queues, management has to be auto-create -->
<address-setting match="activemq.management#">
<dead-letter-address>DLQ</dead-letter-address>
<expiry-address>ExpiryQueue</expiry-address>
<redelivery-delay>0</redelivery-delay>
<!-- with -1 only the global-max-size is in use for limiting -->
<max-size-bytes>-1</max-size-bytes>
<message-counter-history-day-limit>10</message-counter-history-day-limit>
<address-full-policy>PAGE</address-full-policy>
<auto-create-queues>true</auto-create-queues>
<auto-create-addresses>true</auto-create-addresses>
<auto-create-jms-queues>true</auto-create-jms-queues>
<auto-create-jms-topics>true</auto-create-jms-topics>
</address-setting>
<!--default for catch all-->
<address-setting match="#">
<dead-letter-address>DLQ</dead-letter-address>
<expiry-address>ExpiryQueue</expiry-address>
<redelivery-delay>0</redelivery-delay>
<!-- with -1 only the global-max-size is in use for limiting -->
<max-size-bytes>-1</max-size-bytes>
<message-counter-history-day-limit>10</message-counter-history-day-limit>
<address-full-policy>PAGE</address-full-policy>
<auto-create-queues>true</auto-create-queues>
<auto-create-addresses>true</auto-create-addresses>
<auto-create-jms-queues>true</auto-create-jms-queues>
<auto-create-jms-topics>true</auto-create-jms-topics>
</address-setting>
<address-setting match="exampleQueue">
<dead-letter-address>DLQ</dead-letter-address>
<redelivery-delay>1000</redelivery-delay>
<max-delivery-attempts>3</max-delivery-attempts>
<max-size-bytes>-1</max-size-bytes>
<page-size-bytes>1048576</page-size-bytes>
<message-counter-history-day-limit>10</message-counter-history-day-limit>
<address-full-policy>PAGE</address-full-policy>
</address-setting>
</address-settings>
</core>
</configuration>
for slave it's almost the same structure. I won't post it.
Is it right configuration or is it over engineered and can be used just single authentification ? if yes how it would look like.
Thanks

Most SSL use-cases use 1-way SSL. In those cases the server (whether that's a web server, file server, message broker, etc.) hosts an SSL certificate and the client must "trust" that certificate in order to successfully complete the SSL handshake. Usually a server's SSL certificate is signed by a trusted authority (e.g. VeriSign, Digicert, Thawte, etc.) and clients implicitly trust them. This is how the vast majority of SSL is done on the web.
However, when using "self-signed" certificates, as you're doing, the server's certificate isn't signed by a trusted authority so the client has to manually import the certificate into its "trust store."
With 2-way (or "mutual") SSL both the server and the client have SSL certificates and both the server and the client have to trust the other's certificate in order to successfully complete the SSL handshake. This kind of configuration is relatively rare and usually only required in highly secured environments where explicit trust must be established by all parties. It may also be useful for ActiveMQ Artemis clients because certificate details can be used in lieu of username & password for authentication. The configuration details for this are discussed in the ActiveMQ Artemis security documentation.
Since you've specified needClientAuth=true on your acceptor in broker.xml you are requiring 2-way SSL. The ActiveMQ Artemis transport documentation states:
needClientAuth
This property is only for an acceptor. It tells a client connecting to this acceptor that 2-way SSL is required. Valid values are true or false. Default is false.
Using 2-way SSL can be a significant configuration burden because it requires work for every client on both the client and the server (i.e. to generate and import/trust the proper certificates).
Configuration for 1-way SSL is much simpler. For example, you would only need to run these commands:
# Create a broker key and cert - import the keypair and cert into the broker keystore
openssl req -newkey rsa:2048 -nodes -keyout broker_keypair.pem -x509 -days 65000 -out broker_cert.pem
openssl pkcs12 -inkey broker_keypair.pem -in broker_cert.pem -export -out broker_ks.p12
# Create a truststore for the client, and import the broker's certificate. This establishes that the client "trusts" the broker:
keytool -import -alias broker -keystore client_ts.p12 -file broker_cert.pem -deststoretype pkcs12
And your connectors and acceptors would be configured like so:
<connectors>
<connector name="netty-connector">tcp://amq1:61616?sslEnabled=true;trustStorePath=client_ts.p12;trustStorePassword=artemis</connector>
</connectors>
<acceptors>
<acceptor name="netty-acceptor">tcp://amq1:61616?sslEnabled=true;keyStorePath=broker_ks.p12;keyStorePassword=artemis</acceptor>
</acceptors>

Related

SSL configuration is not working in Wildfly 26.0.1

We are trying to migrate Wildfly from 8.1.0.Final to 26.0.1.Final. Currently Wildfly is running in standalone mode hence standalone.xml is in used for configurations and no domain configuration so far.
Everything is working that includes, management console, package deployments etc but requesting URL with https gives us "This site can't be reached". It appears there is something wrong with SSL configuration in Wildfly 26.0.1.Final because same SSL certificate have been used in version 8.1.0.Final.
Here is SSL/TLS configuration we are using:
<tls>
<key-stores>
<key-store name="abc-keystore">
<credential-reference clear-text="clearpasswordonetwothree"/>
<implementation type="JKS"/>
<file path="abc-keystore.jks" relative-to="jboss.server.config.dir"/>
</key-store>
</key-stores>
<key-managers>
<key-manager name="applicationKM" key-store="abc-keystore">
<credential-reference clear-text="clearpasswordonetwothree"/>
</key-manager>
</key-managers>
<server-ssl-contexts>
<server-ssl-context name="applicationSSC" key-manager="applicationKM"/>
</server-ssl-contexts>
</tls>
We've removed generate-self-signed-certificate-host="localhsot" from configuration because certificate is not self-signed in our case.
Like I mentioned before, same SSL certificate have been used in version 8.1.0.
Please be noted that this is specifically related to version 26.0.1.Final and I have no idea if any more configuration is required apart from the above.
Any help is highly appreciated.
This is how I sorted out with the help of Wildfly support. In my case it's standalone mode.
TLS Block:
<tls>
<key-stores>
<key-store name="applicationKS">
<credential-reference clear-text="password"/>
<implementation type="JKS"/>
<file path="C:\wildfly26\application.keystore.jks"/>
</key-store>
</key-stores>
<key-managers>
<key-manager name="applicationKM" key-store="applicationKS" generate-self-signed-certificate-host="localhost">
<credential-reference clear-text="password"/>
</key-manager>
</key-managers>
<server-ssl-contexts>
<server-ssl-context name="applicationSSC" protocols="TLSv1.2" key-manager="applicationKM"/>
</server-ssl-contexts>
</tls>
Reference SSL context in https-listener
<https-listener name="https" socket-binding="https" ssl-context="applicationSSC" enable-http2="true"/>
Socket Binding under socket-binding-group
Change port from 8443 to 443
<socket-binding name="https" port="${jboss.https.port:443}"/>
Configure Interface
<interfaces>
<interface name="management">
<inet-address value="${jboss.bind.address.management:127.0.0.1}"/>
</interface>
<interface name="public">
<inet-address value="${jboss.bind.address:0.0.0.0}"/>
</interface>
</interfaces>
I ran into the same problem since they removed the security realms. I used the top part of this manual: https://docs.jboss.org/author/display/WFLY/Simple%20SSL%20Migration.html
My setup was that I had a .cer certificate and key, I had to re-create the keystore using these two answers: How to create an empty java trust store? and How to import an existing X.509 certificate and private key in Java keystore to use in SSL?
create keystore with dummy certificate: keytool -genkeypair -alias boguscert -storepass changeit -keypass changeit -keystore server.keystore -dname "CN=Developer, OU=Department, O=Company, L=City, ST=State, C=CA"
delete dummy certificate from keystore: keytool -delete -alias boguscert -storepass changeit -keystore server.keystore
Create pkcs12 certificate from key and .crt file openssl pkcs12 -export -in <SERVERNAME>.crt -inkey <SERVERNAME>.key -out server.p12 -name server
import pkcs12 certificate into empty keystore: keytool -importkeystore -deststorepass changeit -destkeypass changeit -destkeystore server.keystore -srckeystore server.p12 -srcstoretype PKCS12 -srcstorepass changeit -alias server
I then followed the top part of jboss documentation I linked above above using the the wildfly-cli located in the bin directory. This writes the needed xml into the standalone.xml so make sure you use the vanilla one that ships with wildfly 26.0.1. After that I had to enable the ssl redirection using this: Redirect http requests to https in wildfly 10
Hope it helps
Here is how my Widfly (20) is configured regarding SSL.
Assuming you have already setup a Java keystore whose entry named 'server' is containing your certificate/key, you have to tell Wildfly to look for that particular alias ('server') in your keystore:
<management>
<security-realms>
...
<security-realm name="ApplicationRealm">
<server-identities>
<ssl>
<keystore path="application.keystore" relative-to="jboss.server.config.dir" keystore-password="..." alias="server" key-password="..." generate-self-signed-certificate-host="localhost"/>
</ssl>
</server-identities>

keycloak-12.0.4 wildfly-21.0.2 Connection refused

myapp on wildfly-10 used keycloak-6 for authencation for 2 years without any issue. The SSL certificate expired and I have reinstall a new SSL and update to wildfly-21 and keycloak-12.
I am getting a Connection refused error.
Here is the list of different steps:
I installed Sectigo Essential Wildcard SSL for keycloak-12 as the following:
I issued a certificat from mydomain.net.csr
I received 3 files: _mydomain_net.crt, AAA_Certificate_Services.crt and USERTrust_RSA_Certification_Authority.crt
openssl pkcs12 -export -in _mydomain.crt -inkey mydomain.net.key -out mydomain.net.pl12 -name default -CAfile AAA_Certificate_Services.crt -caname root
keytool -importkeystore -destkeystore mydomain.net.jks -srckeystore mydomain.net.pl12 -srcstoretype PKCS12 -alias default
cp mydomain.net.jks keycloak-12.0.4/standalone/configuration/
I configured keycloak standalone.xml as the following:
<security-realm name="UndertowRealm">
<server-identities>
<ssl>
<keystore path="mydomain.net.jks" relative-to="jboss.server.config.dir" keystore-password="mypass" />
</ssl>
</server-identities>
...
</security-realm>
<https-listener name="https" socket-binding="https" security-realm="UndertowRealm" enable-http2="true"/>
<host name="default-host" alias="localhost">
<location name="/" handler="welcome-content"/>
<http-invoker security-realm="UndertowRealm"/>
</host>
...
<spi name="truststore">
<provider name="file" enabled="true">
<properties>
<property name="file" value="${jboss.server.config.dir}/mydomain.net.jks"/>
<property name="password" value="mypass"/>
<property name="hostname-verification-policy" value="WILDCARD"/>
<property name="disabled" value="false"/>
</properties>
</provider>
</spi>
I added the certificated to the jvm
cp _mydomain_net.cert to /usr/lib/jvm/java-8-oracle/jre/lib/security/
keytool -import -alias ca -file _mydomain.net.crt -keystore cacerts -storepass mypass
At this level I can access my keycloak installation via https without any issue.
I configured wildfly-21.0.2 as the following:
cp mydomain.net.jks standalone/configuration/mydomain.net.jks
I added a certificated to the jvm of my wildfly-21.0.2 server
cp _mydomain_net.cert to /usr/lib/jvm/java-8-oracle/jre/lib/security/
keytool -import -alias ca -file _mydomain_net.crt -keystore cacerts -storepass mypass
my web.xml
<security-constraint>
<web-resource-collection>
<url-pattern>/home/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>uma_authorization</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>KEYCLOAK</auth-method>
</login-config>
<security-role>
<role-name>uma_authorization</role-name>
</security-role>
I can't connect myapp from wildfly-21 to keycloak-12, the error:
[org.keycloak.adapters.KeycloakDeployment] (default task-1) Failed to load URLs from https://iam.mykeycloak.net/auth/realms/demo/.well-known/openid-configuration: java.net.ConnectException: Connection refused (Connection refused)
I am working on this issue for three days without any success and I have no idea on how to solve this problem. Thanks in advance for any idea/suggestion.
https port was missing.
change https://iam.mykeycloak.net to https://iam.mykeycloak.net:8543

Log4j2 TCP-SSL Appender configuration in log4j2-config.xml

I am planning to configure a Log4j2 Socket Appender with a TCP-SSL Appender.
Here is the configuration I see in Log4j2 website.
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp" packages="">
<Appenders>
<Socket name="socket" host="localhost" port="9500">
<JsonLayout properties="true"/>
<SSL>
<KeyStore location="log4j2-keystore.jks" password="guessme!"/>
<TrustStore location="truststore.jks" password="guessme!"/>
</SSL>
</Socket>
</Appenders>
<Loggers>
<Root level="error">
<AppenderRef ref="socket"/>
</Root>
</Loggers>
</Configuration>
In this config, what do the Keystore and TrustStore files contain? I don't have these files.
I want to send my logs to Splunk TCP port.
Do I need to create truststore.jks with SSL certs from my Splunk server so that my server trusts Splunk?
What is log4j2-keystore.jks, and where can I download it? Do I need a KeyStore file? What should go in it? Does Splunk need a corresponding public key or trusted certs?
The keystore contains your personal key and public key if you have and want to use them. It can be left out completely.
The truststore contains the server's certificate. You can download and package it as jks like this:
$ echo -n | openssl s_client -connect log-server.tld:5010 -servername log-server.tld \
| sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' | tee "server.crt"
$ keytool -import -alias log-server-certificate-alias -keystore log-server-cert.jks -file server.crt
The latter prompts you for the password you will then use in the log configuration.
I had a similar issue with logstash and posted a brief summary of my findings here: https://rekowski.info/home/technical/java/log4j2-socket-appender-logstash-kibana-ssl-tls.md

CA based Tomcat client authentication

I have troubles setting up a mutual authentication scheme using Tomcat 7 in Centos 7.
The server authentication is working as expected, but I am stuck on the client authentication.
The server certificate and the clients certificates are issued by the same CA. My goal is to allow any client with a certificate issued by this CA.
So far, my server.xml looks like this for the concerned connector:
<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol" maxThreads="150"
scheme="https" secure="true" sslProtocol="TLSv1.2" sslEnabledProtocols="TLSv1,TLSv1.1,TLSv1.2" SSLEnabled="true"
keystoreFile="/absolute/path/to/mykeystore.jks" keystorePass="P455W0RD" keyAlias="myalias"
clientAuth="true"
truststoreFile="/absolute/path/to/mykeystore.jks" truststorePass="P455W0RD"
/>
When the keystore contains the client certificate, the mutual authentication successes.
However, when the keystore contains only the CA, the mutual authentication fails.
I have generated my keystore with the commands below:
openssl pkcs12 -export -in server.crt -inkey server.key -out server.p12 -name myalias -CAfile ca.crt -caname root
keytool -importkeystore -deststorepass <pass> -destkeypass <pass> -destkeystore mykeystore.jks -srckeystore server.p12 -srcstoretype PKCS12 -srcstorepass <pass> -alias myalias
keytool -importcert -alias root -keystore mykeystore.jks -storepass <pass> -file ca.crt
I also tried to remove the truststoreFile and truststorePass parameters from the connector, and add the CA to the cacerts in $JAVA_HOME/jre/lib/security/, but the mutual authentication still fails.
Could you please indicate me how to set up such a mutual authentication configuration?

CAS + SSLHandshakeException + ValidatorException + PKIX path building failed + unable to find valid certification path to requested target

I am working on Central Authentication System (jasig.org) to implementing Single Sign On featute
for my intranet web application. I have two tomcat instance running in my same machine(windows).
Both tomcat instance have been configured to use SSL and have used self-signed sertificate (created using java keytool).
Tomcat1
Cas Server.
server.xml
<Connector port="8443" maxHttpHeaderSize="8192" SSLEnabled="true"
maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
enableLookups="false" disableUploadTimeout="true"
acceptCount="100" scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS"
keystoreFile="C:/Users/sandip.paul/.keystore"
keystorePass="changeit"
truststoreFile="C:/Program Files/Java/jdk1.6.0_20/jre/lib/security/cacerts" />
Tomcat2
myWebApp(using spring security)
server.xml
<Connector port="8663" maxHttpHeaderSize="8192" SSLEnabled="true"
maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
enableLookups="false" disableUploadTimeout="true"
acceptCount="100" scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS" />
below is the applicationContext-security.xml file of the myWebApp
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:security="http://www.springframework.org/schema/security"
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-2.0.4.xsd">
<!--
Enable security, let the casAuthenticationEntryPoint handle all intercepted urls.
The CAS_FILTER needs to be in the right position within the filter chain.
-->
<security:http entry-point-ref="casProcessingFilterEntryPoint" auto-config="true">
<security:intercept-url pattern="/protected/**" access="IS_AUTHENTICATED_FULLY" />
</security:http>
<!--
Required for the casProcessingFilter, so define it explicitly set and
specify an Id Even though the authenticationManager is created by
default when namespace based config is used.
-->
<security:authentication-manager alias="authenticationManager" />
<!--
This section is used to configure CAS. The service is the
actual redirect Client URL that will be triggered after the CAS login sequence.
-->
<bean id="serviceProperties" class="org.springframework.security.ui.cas.ServiceProperties">
<property name="service" value="https://obll1973.abc.com:8663/myWebApp/j_spring_cas_security_check"/>
<property name="sendRenew" value="false"/>
</bean>
<!--
The customUserDetailsService provides ROLE & other Details and
create an object of UserDetail for this application.
-->
<bean id="customUserDetailsService"
class="edu.sandip.cas.client.authentication.CustomUserDetailsService">
</bean>
<!--
The CasProcessingFilter has very similar properties to the
AuthenticationProcessingFilter (used for form-based logins).
The CAS Processing filter handles the redirect from the CAS server
and starts the ticket validation.
-->
<bean id="casProcessingFilter" class="org.springframework.security.ui.cas.CasProcessingFilter">
<security:custom-filter after="CAS_PROCESSING_FILTER"/>
<property name="authenticationManager" ref="authenticationManager"/>
<property name="authenticationFailureUrl" value="/casfailed.jsp"/>
<property name="defaultTargetUrl" value="/"/>
</bean>
<!--
The entryPoint intercepts all the CAS authentication requests.
It redirects to the CAS loginUrl for the CAS login page.
-->
<bean id="casProcessingFilterEntryPoint"
class="org.springframework.security.ui.cas.CasProcessingFilterEntryPoint">
<property name="loginUrl" value="https://obll1973.abc.com:8443/cas/login"/>
<property name="serviceProperties" ref="serviceProperties"/>
</bean>
<!--
Handles the CAS ticket processing.
-->
<bean id="casAuthenticationProvider"
class="org.springframework.security.providers.cas.CasAuthenticationProvider">
<security:custom-authentication-provider />
<property name="userDetailsService" ref="customUserDetailsService" />
<property name="serviceProperties" ref="serviceProperties" />
<property name="ticketValidator">
<bean class="org.jasig.cas.client.validation.Cas20ServiceTicketValidator">
<constructor-arg index="0" value="https://obll1973.abc.com:8443/cas" />
</bean>
</property>
<property name="key" value="an_id_for_this_auth_provider_only"/>
</bean>
<!--
To access request.getRemoteUser() from client application
-->
<bean id="wrappingFilter" class="org.jasig.cas.client.util.HttpServletRequestWrapperFilter" />
</beans>
The issue I am facing is the below exception:
java.lang.RuntimeException: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
org.jasig.cas.client.util.CommonUtils.getResponseFromServer(CommonUtils.java:341)
org.jasig.cas.client.util.CommonUtils.getResponseFromServer(CommonUtils.java:305)
org.jasig.cas.client.validation.AbstractCasProtocolUrlBasedTicketValidator.retrieveResponseFromServer(AbstractCasProtocolUrlBasedTicketValidator.java:50)
org.jasig.cas.client.validation.AbstractUrlBasedTicketValidator.validate(AbstractUrlBasedTicketValidator.java:207)
org.springframework.security.providers.cas.CasAuthenticationProvider.authenticateNow(CasAuthenticationProvider.java:145)
org.springframework.security.providers.cas.CasAuthenticationProvider.authenticate(CasAuthenticationProvider.java:131)
org.springframework.security.providers.ProviderManager.doAuthentication(ProviderManager.java:188)
org.springframework.security.AbstractAuthenticationManager.authenticate(AbstractAuthenticationManager.java:46)
org.springframework.security.ui.cas.CasProcessingFilter.attemptAuthentication(CasProcessingFilter.java:94)
org.springframework.security.ui.AbstractProcessingFilter.doFilterHttp(AbstractProcessingFilter.java:258)
org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:390)
org.springframework.security.ui.logout.LogoutFilter.doFilterHttp(LogoutFilter.java:89)
org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:390)
org.springframework.security.context.HttpSessionContextIntegrationFilter.doFilterHttp(HttpSessionContextIntegrationFilter.java:235)
org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:390)
org.springframework.security.util.FilterChainProxy.doFilter(FilterChainProxy.java:175)
org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:236)
org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167)
Steps to replicate the above exception:
1) I tried accessing myWebApp using https://obll1973.abc.com:8663/myWebApp/protected/
2) It is getting redirected to cas server i.e. https://obll1973.abc.com:8443/cas/login and after providing username/password
Here the exception caught once myWebApp again send the request to cas server to validate the generated Token.
Any suggestion/help would be highly appriciated.
Your Spring-CAS configuration looks fine.
The one and only reason SSLHandshakeException appears is due to the improper import of the SSL key into the created keystore or the JVM keystore.
During key creation have you followed the following
Note : the alias name that is the CN (here it is cas) should be same name as the machine's hostname.
to find the machine's host name, in console or command promt just type "hostname" without quotes.
Create a directory under root named app
[root#localhost app]# keytool -genkey -alias cas -keyalg RSA -keystore
.cas -storepass caspasswd
What is your first and last name? [Unknown]: cas What is the name
of your organizational unit? [Unknown]: MYCOMPANY What is the name
of your organization? [Unknown]: MYCOMPANY What is the name of your
City or Locality? [Unknown]: Bangalore What is the name of your
State or Province? [Unknown]: Karnataka What is the two-letter
country code for this unit? [Unknown]: IN Is CN=cas, OU=MYCOMPANY,
O=MYCOMPANY, L=Bangalore, ST=Karnataka, C=IN correct? [no]: yes
Enter key password for (give the password mentioned above -- i.e
caspasswd in this case)
(RETURN if same as keystore password): Re-enter new password:
[root#localhost app]# keytool -exportcert -alias cas -file cas.crt
-keystore .cas Enter keystore password: Certificate stored in file
[root#localhost app]# ls cas.crt softwares test.class test.java
tomcat7027CAS
[root#localhost app]# keytool -import -alias cas -file cas.crt
-keystore /app/softwares/jdk1.6.0_27/jre/lib/security/cacerts Enter keystore password: Owner: CN=cas, OU=MYCOMPANY, O=MYCOMPANY,
L=Bangalore, ST=Karnataka, C=IN Issuer: CN=cas, OU=MYCOMPANY,
O=MYCOMPANY, L=Bangalore, ST=Karnataka, C=IN Serial number: 510a6a63
Valid from: Thu Jan 31 18:28:11 IST 2013 until: Wed May 01 18:28:11
IST 2013 Certificate fingerprints:
MD5: 52:8E:2E:74:C6:57:CD:B3:B0:B6:6C:17:D9:0D:77:F3
SHA1: 1F:AA:4C:22:B9:16:DC:AA:D4:87:07:CF:DD:B2:11:A6:AE:36:9A:DB
Signature algorithm name: SHA1withRSA
Version: 3 Trust this certificate? [no]: yes Certificate was added to keystore
[root#localhost app]# keytool -list -keystore
/app/softwares/jdk1.6.0_27/jre/lib/security/cacerts -alias cas Enter
keystore password: cas, Jan 31, 2013, trustedCertEntry, Certificate
fingerprint (MD5): 52:8E:2E:74:C6:57:CD:B3:B0:B6:6C:17:D9:0D:77:F3
[root#localhost app]#
And Inside your tomcat server.xml you also use the https connector as following
<Connector port="8443" protocol="org.apache.coyote.http11.Http11Protocol" SSLEnabled="true"
maxThreads="150" scheme="https" keystoreFile="/app/.cas" keystorePass="mykeypassword"
secure="true" connectionTimeout="240000"
clientAuth="false" sslProtocol="TLS" allowUnsafeLegacyRenegotiation="true" />
<!-- Define an AJP 1.3 Connector on port 8009 -->
<Connector port="8069" protocol="AJP/1.3" redirectPort="8443" />
The above key was for CAS Server.
You can create your own seperate key for the application.
But both key should be imported to the JVM cacerts keystore (How to : is mentioned below)
Now the most important part :
suppose your CAS Server alias name is cas
and your application Server alias name is myapp
keep both the keys cas.crt and myapp.crt in both servers to import into JVM
Do the following in both server :
1) keytool -import -alias cas -file /app/cas.crt -keystore
/usr/java/jdk1.5.0_22/jre/lib/security/cacerts
2) keytool -import -alias myapp -file /app/cas.crt -keystore
/usr/java/jdk1.5.0_22/jre/lib/security/cacerts
To verify use the following commands --
1) keytool -list -v -keystore
/usr/java/jdk1.5.0_22/jre/lib/security/cacerts -alias cas
2) keytool -list -v -keystore
/usr/java/jdk1.5.0_22/jre/lib/security/cacerts -alias myapp
Be sure about the Java--JRE--LIB--SECURITY--CACERTS file if using mutiple versions of java
This will remove your error.
Note :
If after giving proper user credential browser is showing blank white page,
modify the system's host file (/etc/hosts in linux and c:\windows\system32\driver\etc\hosts in windows)
add the cas server ip there
eg.
162.25.250.60 myapp
162.25.250.81 cas
Any doubt can be clarified.
You can refer the following :
https://wiki.jasig.org/display/CASUM/SSL+Troubleshooting+and+Reference+Guide