Sunday, January 18, 2015

FATAL Alert: BAD_CERTIFICATE - A corrupt or unuseable certificate was received

I am trying to invoke a third part web-service (https) through the Oracle Service Bus/Weblogic Server. However whenever I try to use a business service to connect I get the following error message:

The invocation resulted in an error: FATAL Alert:BAD_CERTIFICATE - A corrupt or unuseable certificate was received..


WL doesn't like wild card certs.

If you submit your request to "someserver.thirdparty.com" and you get back the above, you'll get the error.

You can 


* Disable host name verification ( never a pleasant thought )
* Write your own custom hostname verification
* Ask them to get a cert specific to their host ( with a CN of "someserver.mdsol.com, for instance ).
 


* Or apply the following method as part of Oracle given solution for WLS 10.3.6. or 10.3.5 and below  

In WLS releases before WLS 11.1.1.5 (WLS 10.3.5), WebLogic Server's hostname verification code did not support wildcard certificates. Thus as per a product enhancement, we have created a separate hostname verification code, which allows wildcard certificates.

Thus in order to have this functionality on WLS 10.3.5 and below, we have Patch 10215257 for WLS 10.3.0, 10.3.4, and 10.3.5.
NOTE: This wildcard implementation is embedded in the binaries of WLS 10.3.6 and 12.1.1.0, thus there is no requirement for a patch on those versions and higher.

Once we apply the apprropriate patch we need to do the following:

Add the server start-up parameter (in the java_options):
-Dweblogic.security.SSL.hostnameVerifier=weblogic.security.utils.SSLWLSWildcardHostnameVerifier,/div>
Navigate to Admin Console -> server_name -> SSL -> Advanced. Check the checkbox Use JSSE.

This has to be done on all the servers where we are planning to use the wild card certificate. If you are using WLS 10.3.6+ or WLS 12.1.1.0+, do the following:

Enable "Use JSSE."
Navigate to Admin console -> server_name -> SSL -> Advanced ->. Check the checkbox Use JSSE.
Select the value "weblogic.security.utils.SSLWLSWildcardHostnameVerifier" from the dropdown list of "Hostname verfication" parameters.

Note:

Weblogic server by default implements certicom SSL. In release WLS 10.3.4 the JSSE is implemented and certcom deprecated. As mentioned above.

But wth previous version i.e. 10.3 which hasn't got this option available in the console, we can implement the following parameters to enable Sun SSL implementation instead of certicom:

-Djava.protocol.handler.pkgs=com.sun.net.ssl.internal.www.protocol
-Dssl.SocketFactory.provider=com.sun.net.ssl.internal.SSLSocketFactoryImpl
-DUseSunHttpHandler=true
-Dweblogic.wsee.client.ssl.usejdk=true (for webservice clients)

***If the trust authority of weblogic default certificate and provider's certificate is same then you don't need to import its certificate in your trust store.

Saturday, January 10, 2015

Weblogic WLST Script to Create JMS Artifacts in Clustered Environment

As a part one event, I had developed a WLST script to deploy JMS artifacts in a clustered environment. The script can deploy as many JMS Servers, JDBC Stores, File Stores, DQueues, DTopics with JMS Modules and Sub Deployments in a clustered web-logic environment.

Below figure depicts conventionally followed JMS Deployment Architecture.
JMS Deployment Architecture





Now let us start with the script :

There are two files as a whole. One is the python script or wlst script and the other is a properties file which contains metadata for the script.

1. createGenieJMSResources.py
2. crowdGenieJMS.properties

Let me first lay down the properties file contents.


################Start of the properties file###############

username=weblogic
password=weblogic@123
providerURL=t3://localhost:7001

#Cluster name on which the module is to be targeted
jms_clusterName=GenieCluster

#jms module and its sub deployment
jms_module=GenieModule

#files stores and data source and their respective store directory path - note: name assumed is "Store_"+jms_persistent_store_type+"_"+jms_targetManageServerName
jms_persistent_store_type=File,JDBC
optional_explicit_fileStoreDirectory=
dataSourceJNDIName=localDS

#manage servers which are to be targeted by JMS Servers and file stores respectively - note: name assumed for JMSServer is jms_module+"_JMSServer_"+jms_targetManageServerName
jms_targetManageServerName=Server-Genie1,Server-Genie2

#Destination Name and their respective jndi
jms_destination_jndi_name=jms/GenieQueue1,jms/GenieQueue2,jms/GenieQueue3,jms/GenieQueue4,jms/GenieQueue5,jms/GenieTopic1,jms/GenieTopic2,jms/GenieTopic3,jms/GenieTopic4
jms_type=Queue,Queue,Queue,Queue,Topic,Topic,Topic,Topic

#Connection Factories and their respective jndi's
jms_connFacJNDIName=fac/GenieConnFac1,fac/GenieConnFac2
xa_conn_flag=true,false

#flag for logging - if true then logs in the domain path with genieWLST.log else it stdouts on the console
log_file=true
log_path=

#flag to check if existing resources needs to be deleted and recreated, or error should log/pop out.
delete_if_exist_flag=true

#################End of the properties file#################

The important thing to note in the properties file is the comma separated values of several properties like jms_destination_jndi_name, jms_targetManageServerName. The script reads the values in a array loop on values split delimited by the ','. Look at the script code to better understand.
There are also naming convention to the file or data stores.

Now let us look at the script :


#the part contains import from java python lib. FOS and FIS is required for loading the properties file.
from java.io import FileOutputStream
from java.io import FileInputStream
from java.util import Properties
from java.io import File
import sys

try:


# Load the properties file.
def loadProperties(fileName):
properties = Properties()
input = FileInputStream(fileName)
properties.load(input)
input.close()

result= {}

for entry in properties.entrySet(): result[entry.key] = entry.value

return result


properties = loadProperties("crowdGenieJMS.properties")


#This is it checks if the WLST output files is to be generated a a user defined path or default same directory path where WLST script is kept.
if(properties['log_path']==""):
logFilePath="genieWLST.log"
else:
logFilePath=properties['log_path']+"//genieWLST.log"

#Setting the output log file
if(properties['log_file'] == "true"):
f = File(logFilePath)
fos = FileOutputStream(f)
theInterpreter.setOut(fos)


# Initializing

username = properties['username']

password = properties['password']
url = properties['providerURL']

moduleName = properties['jms_module']

subDeploymentName = moduleName+"SubDeployment"
storeType = properties['jms_persistent_store_type']

destinationJNDIName = properties['jms_destination_jndi_name']
destinationType = properties['jms_type']

CFJNDIName = properties['jms_connFacJNDIName']

clusterName = properties['jms_clusterName']


targetms = properties['jms_targetManageServerName']



# Connect to Admin Server

connect(username, password, url)
adminServerName = cmo.adminServerName


# Delete old resources, if they exist.

def deleteIgnoringExceptions(mbean):
try: delete(mbean)
except: pass

def startTransaction():
edit()
startEdit()

def endTransaction():

save()
activate(block="true")


def createUDTopic(topicName, jndiTopicName):

cd('/JMSSystemResources/'+moduleName+'/JMSResource/'+moduleName) 
udt1 = create(topicName, "UniformDistributedTopic")
udt1.JNDIName = jndiTopicName

cd("UniformDistributedTopics/"+topicName)
cmo.setSubDeploymentName(subDeploymentName)
cd("/")


def createUDQueue(qname, qjndiname):

cd('/JMSSystemResources/'+moduleName+'/JMSResource/'+moduleName)
udq1 = create(qname, "UniformDistributedQueue")
udq1.JNDIName = qjndiname

cd("UniformDistributedQueues/"+qname)
cmo.setSubDeploymentName(subDeploymentName)
cd("/")

def createCF(cfname, cfjndiname, xaEnabled):

cd('/JMSSystemResources/'+moduleName+'/JMSResource/'+moduleName)
cf = create(cfname, "ConnectionFactory")
cf.JNDIName = cfjndiname
cf.subDeploymentName = subDeploymentName

# Set XA transactions enabled
if (xaEnabled == "true"):
cf.transactionParams.setXAConnectionFactoryEnabled(1)
cd("/")

def createJMSModule():

cd('/JMSSystemResources')
jmsModule = create(moduleName, "JMSSystemResource")

cd('/JMSSystemResources/'+moduleName)
set('Targets',jarray.array([ObjectName('com.bea:Name='+clusterName+',Type=Cluster')], ObjectName))

# Create and configure JMS Subdeployment for this JMS System Module

sd = create(subDeploymentName, "SubDeployment")

cd('SubDeployments/'+subDeploymentName)

objName = ""
for mserver in targetms.split(','):
objName = objName + "ObjectName('com.bea:Name="+moduleName+"_JMSServer_"+mserver+",Type=JMSServer'), " 

objName="set('Targets',jarray.array(["+objName[:-2]+"], ObjectName))"

# executing python command to set target implicitly
exec objName

def createJMSServer():

i=0
ds=0
for mserver in targetms.split(','):

startTransaction()

# Assumed naming conventions
jmsServerName = moduleName+"_JMSServer_"+mserver
storeName = "Store_"+storeType.split(',')[i]+"_"+mserver


# Delete existing JMS Server and its persistent store
if(properties['delete_if_exist_flag']== "true"):
cd("/JMSServers")
deleteIgnoringExceptions(jmsServerName)

cd("/"+storeType.split(',')[i]+"Stores")
deleteIgnoringExceptions(storeName)

#Create JDBC Stores or File Stores
if(storeType.split(',')[i] == "JDBC"):
cd('/')
dsName = properties['dataSourceJNDIName'].split(',')[ds]
store = cmo.createJDBCStore(storeName)

cd('/JDBCStores/'+storeName)

cmo.setDataSource(getMBean('/SystemResources/'+dsName))
set('Targets',jarray.array([ObjectName('com.bea:Name='+mserver+',Type=Server')], ObjectName))
cmo.setPrefixName("GENIE_T_LOG_"+dsName)
ds=ds+1
else:
cd('/')
fileDir = properties['optional_explicit_fileStoreDirectory']
if fileDir == "":
fileDir = cmo.rootDirectory+"\\fileStores"+storeName

store = cmo.createFileStore(storeName)
store.setDirectory(fileDir)
cd('/FileStores/'+storeName)
set('Targets',jarray.array([ObjectName('com.bea:Name='+targetms.split(',')[i]+',Type=Server')], ObjectName))

endTransaction()
#Committed the creation of filestores

startTransaction()
cd("/JMSServers")
# Create JMS server and assign the Filestore

jmsServer = create(jmsServerName, "JMSServer")
jmsServer.setPersistentStore(store)

cd(jmsServerName)
set('Targets',jarray.array([ObjectName('com.bea:Name='+mserver+',Type=Server')], ObjectName))

i=i+1
endTransaction()

# The creation flow starts from here


if(properties['delete_if_exist_flag']== "true"):


startTransaction()
cd("/JMSSystemResources")
deleteIgnoringExceptions(moduleName)
endTransaction()

# Create JMS Servers along with JDBCStores or Filestores , delete the existing if required.
createJMSServer()


startTransaction()
# Create JMS Module and its subdeployment
createJMSModule()

# Create Queues and Topics : The names are same as the JNDI name tagged to the assumed Subbdeployment
di=0
for dtype in destinationType.split(','):
dname = destinationJNDIName.split(',')[di]
if(dtype == "Queue"):
createUDQueue(dname, dname)

if(dtype == "Topic"):
createUDTopic(dname, dname)
di=di+1

# Create Connection Factory with name same as JNDI tagged to the assumed Subdeployment
ci=0
for cf in CFJNDIName.split(','):
createCF(cf,cf, properties['xa_conn_flag'].split(',')[ci])
ci=ci+1

endTransaction()
except Exception, e:
dumpStack()
print e
cancelEdit("y")
#raise

disconnect()


stopRedirect()

exit()

Code shared in the below link :

https://drive.google.com/folderview?id=0B5jwUx0GPlTOZlZnNUtTNHFQYVE&usp=sharing