- WSO2 Identity Server (IS) as Key Distribution Center (KDC)
- Active directory (AD) as the KDC
I would like to thank Prabath for permitting me to copy and modify some of the code he used to demonstrate in his posts.
WSO2 Identity Server (IS) as the Key Distribution Center (KDC)
In this procedure we need to have WSO2 IS and WSO2 ESB setup in two server machines. (You may try this with the same server with two different port offsets for WSO2 IS and WSO2 ESB). It’s assumed that you have configured the two servers beyond this point. Look at ESB and IS documentation for reference at [4] and [5]. WSO2 IS can be used in a standalone mode (without any external database setup) for you to work on this.
In WSO2 IS (here we used IS version 5.0.0), let’s setup the KDC.
First we have to enable the KDC. Open embedded-ldap.xml and enable KDC as below.
<KDCServer> <Property name="name">defaultKDC</Property> <Property name="enabled">true</Property> <Property name="protocol">UDP</Property> <Property name="host">localhost</Property> <Property name="port">${Ports.EmbeddedLDAP.KDCServerPort}</Property> <Property name="maximumTicketLifeTime">8640000</Property> <Property name="maximumRenewableLifeTime">604800000</Property> <Property name="preAuthenticationTimeStampEnabled">false</Property> </KDCServer>If you want to change the default realm of the KDC, change the “realm” property. By default it’s WSO2.ORG. We’ll keep it as it’s in this case for simplicity.
<Property name="realm">WSO2.ORG</Property>We can also enable the KDC setting in the user-mgt.xml. Enable the following property in the UserStoreManager.
<Property name="kdcEnabled">true</Property>Create a file named jaas.conf with following contents and place inside <IS_HOME>/repository/conf/security directory.
Server { com.sun.security.auth.module.Krb5LoginModule required useKeyTab=false storeKey=true useTicketCache=false isInitiator=false; }; Client { com.sun.security.auth.module.Krb5LoginModule required useTicketCache=false; };Create a file name krb5.conf with following contents and place it in <IS_HOME>/repository/conf/security directory. This says your KDC locates in the current machine.
[libdefaults] default_realm = WSO2.ORG default_tkt_enctypes = rc4-hmac des-cbc-md5 default_tgs_enctypes = rc4-hmac des-cbc-md5 dns_lookup_kdc = true dns_lookup_realm = false [realms] WSO2.ORG = { kdc = 127.0.0.1 }Now let’s start the WSO2 IS Server.
Once started the server, we have to create a Service Principal (SPN) and a client principal to use with kerberos ticket granting system (TGS). Once the server is started, navigate to Configure -> Kerberos KDC -> Service Principals and click “Add new Service Principal”. Provide a service principal name, description and a password. In this case we used the following service principal name.
SPN Name : esb/localhost@WSO2.ORG
Now create a new user by navigating to Configure -> Users and Roles -> Users -> Add User.
In our case I have added a user name “test” with a password. This will be the client principal.
That’s all with WSO2 IS KDC configuration.
Let’s now configure security in a sample proxy in WSO2 ESB (We used WSO2 ESB 4.8.1). In my case I’ve secured the default echo proxy. You may do the same for any other proxy.
Configuring ESB for kerberos.
Add the following into jass.conf file and place it in <ESB_HOME>/repository/conf/security directory. Note the principal name configuration
Server { com.sun.security.auth.module.Krb5LoginModule required useKeyTab=false storeKey=true useTicketCache=true isInitiator=false principal="esb/localhost@WSO2.ORG"; };Add the following to the krb5.conf and place it in in <ESB_HOME>/repository/conf/security directory. Configure the ip address of the WSO2 IS in kdc section. If the WSO2 IS is running in the same server as WSO2 ESB, this is the loop back address 127.0.0.1, which is the case in my scenario. Remember to use all caps for the default_realm.
[libdefaults] default_realm = WSO2.ORG default_tgs_enctypes = des-cbc-md5 default_tkt_enctypes = des-cbc-md5 permitted_enctypes = des-cbc-md5 allow_weak_crypto = true [realms] WSO2.ORG = { kdc = 127.0.0.1:8000 } [domain_realm] .wso2.ORG = WSO2.ORG wso2.ORG = WSO2.ORG [login] krb4_convert = true krb4_get_tickets = false
Now you can try invoking the echo proxy using soap ui and it should fail saying “security header does not found”. This is because the request didn’t contain any security information, such as the kerberos ticket etc. In fact it’s difficult to create a soap ui project to work with kerberos, as the specification requires a format for the soap request, such as signing the message payload from kerberos ticket, having a time stamp and so on.
We have written a java client to cater this (Thanks Prabath, once again for permitting me to use and modify your client). Clients need to incorporate same mechanism to call a kerberos secured proxy in the Java code. Please find the client here. We shall discuss about a .Net client in the next post.
Open this project in IntelliJIDEA or your favorite IDE.
Navigate to the config.properties and configure the keyStorePath, keyStorePassword, axis2ClientPath, policyFilePath and servicEndpoint according to your setup. We are using the default keystore in this setup and the configuration is like the following.
# Kerberos configs keyStorePath=/home/shazni/ProjectFiles/kerberosJavaClient/repo/resources/wso2carbon.jks keyStorePassword=wso2carbon axis2ClientPath=/home/shazni/ProjectFiles/kerberosJavaClient/repo/conf/client.axis2.xml policyFilePath=/home/shazni/ProjectFiles/kerberosJavaClient/repo/conf/policy.xml serviceEndpoint=https://localhost:9448/services/KerberosTestRegNote my ESB run on port offset of 5 hence the port 9448.
Next, open up the policy.xml file and make the rampart configuration changes for client.principal.name, client.principal.password (This should be the user you created in the WSO2 IS), service.principal.name, java.security.krb5.conf, java.security.auth.login.config and javax.security.auth.useSubjectCredsOnly. In my case it’s like the following.
<rampart:RampartConfig xmlns:rampart="http://ws.apache.org/rampart/policy"> <rampart:timestampPrecisionInMilliseconds>true</rampart:timestampPrecisionInMilliseconds> <rampart:timestampTTL>300</rampart:timestampTTL> <rampart:timestampMaxSkew>300</rampart:timestampMaxSkew> <rampart:timestampStrict>false</rampart:timestampStrict> <rampart:nonceLifeTime>300</rampart:nonceLifeTime> <rampart:kerberosConfig> <rampart:property name="client.principal.name">test_carbon.super</rampart:property> <rampart:property name="client.principal.password">test123</rampart:property> <rampart:property name="service.principal.name">esb/localhost@WSO2.ORG</rampart:property> <rampart:property name="java.security.krb5.conf">repo/conf/krb5.conf</rampart:property> <rampart:property name="java.security.auth.login.config">repo/conf/jaas.conf</rampart:property> <rampart:property name="javax.security.auth.useSubjectCredsOnly">true</rampart:property> </rampart:kerberosConfig> </rampart:RampartConfig>
Also open up the krb5.conf file located in the client code and configure your kdc ip address. In this case the ip address of the WSO2 IS server.
Now if you run the client you should see the response of the echo service. You should see an output like the following in the console.
Calling service with parameter - Hello Shazni!!!!!!! Request = <p:echoString xmlns:p="http://echo.services.core.carbon.wso2.org"><in>Hello Shazni!!!!!!!</in></p:echoString> The response is : <ns:echoStringResponse xmlns:ns="http://echo.services.core.carbon.wso2.org"><return>Hello Shazni!!!!!
This client contacts the WSO2 IS KDC to get a kerberos ticket and then uses the rampart library to build the request as compliant to the WS-Security specification and send the request to the proxy. At the ESB server end, the rampart resolves the request and wss4j validates the ticket by decryption and validating the signature of the request payload and call the backend service, if those validation passes. Subsequently gets the response and sign it back with the kerberos key and send the response back, once again in compliance with the WS-Security.
That's all the configurations you got to do. This is a very simple example on how to use keberos security scheme in WSO2 ESB with WSO2 IS.
In the next post I'll show how to configure the ESB with AD based KDC (specifically with a keyTab file, instead of using the SPN and it's password as used in this post)
[1] http://wso2.com/library/articles/2012/07/kerberos-authentication-using-wso2-products/
[2] http://blog.facilelogin.com/2010/12/kerberos-authentication-with-wso2-esb.html
[3] https://malalanayake.wordpress.com/2012/12/13/how-to-invoke-the-echo-service-secured-by-kerberos-in-wso2-esb/
[4] https://docs.wso2.com/display/ESB490/WSO2+Enterprise+Service+Bus+Documentation
[5] https://docs.wso2.com/display/IS510/WSO2+Identity+Server+Documentation
No comments:
Post a Comment