WebLogically
General Oracle WebLogic and Fusion Middleware
Friday, 27 June 2014
SOA 12c Released
https://blogs.oracle.com/soacommunity/entry/soa_suite_12c_is_available
Wednesday, 23 April 2014
OSB 11g: SAML 1.1 Sender Vouches As CSF User
This blog post explains the steps required to secure an OSB proxy service with an OWSM security policy that requires a SAML 1.1 Sender Vouches token and also how to configure OSB such that this proxy can readily be tested from the OSB test console using am identity defined in the Credential Store Framework.
Pre-Requisites
The following are pre-requisites for following this post:
- The OSB domain mus have been configured for OWSM and EM
- An entry in the Credential Store Framework (CSF) for the weblogic username/password
This post explains how to setup the OSB domain to meet these pre-requisites
Applying the Policy
The following procedure will apply the required oracle/wss10_saml_token_service_policy
Policy to the Proxy Service. In this instance the instructions are for the OSB console but the same can be readily achieved in the OEPE IDE.
- Open the Oracle Service Bus Console in your browser (typically http://localhost:7001/sbconsole
- Navigate to the Proxy Service
- Ensure that there is a edit session created in the change center
- Click the "Polcies" tab
- Click the "From OWSM Policy Store" radio button
- Click the "Add" button, this will pop-up a "Select OWSM Policy" window.
- Select radio button next to the
oracle/wss10_saml_token_service_policy
policy in the list - Click the "Submit" button which will close the "Select OWSM Policy" pop-up window
- Click the "Update" button to save the policy change.
- Activate the edit session in the change center
Testing as Anonymously
Attempting to test the proxy such that it generates a SAML assertion containing the "weblogic" user as follows:
Property | Override Value |
---|---|
subject.precedence | true |
csf-key | weblogic |
However this results in an anonymous SAML token being created.
<soap:Header xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<wsse:Security soap:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<saml:Assertion MajorVersion="1" MinorVersion="1" AssertionID="SAML-ItxCC78g5ngixaGfX3cJzg22" IssueInstant="2014-04-22T12:58:19Z" Issuer="www.oracle.com" xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion">
<saml:Conditions NotBefore="2014-04-22T12:58:19Z" NotOnOrAfter="2014-04-22T13:03:19Z"/>
<saml:AuthenticationStatement AuthenticationInstant="2014-04-22T12:58:19Z" AuthenticationMethod="urn:oasis:names:tc:SAML:1.0:am:password">
<saml:Subject>
<saml:NameIdentifier Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified">owsm_anonymous_fe24daa0-bc21-4434-9d8e-148833612e92</saml:NameIdentifier>
<saml:SubjectConfirmation>
<saml:ConfirmationMethod>urn:oasis:names:tc:SAML:1.0:cm:sender-vouches</saml:ConfirmationMethod>
</saml:SubjectConfirmation>
</saml:Subject>
</saml:AuthenticationStatement>
</saml:Assertion>
</wsse:Security>
</soap:Header>
Note the use of owsm_anonymous_fe24daa0-bc21-4434-9d8e-148833612e92
as the username. This is because the subject.precedence
override property on the client policy was true. The same test can be attempted again but this time with the property set to false
to allow the weblogic
user from CSF to be used.
Property | Override Value |
---|---|
subject.precedence | false |
csf-key | weblogic |
As seen in the following screenshot.
However this results in the following error:
An error occurred during web service security outbound request processing [error-code: SecurityHeaderMarshallingError, message-id: <test-message>, proxy: <alsb-test-service>, target: OSBExamplesProject/helloworld/proxy/HelloWorldSAML, operation: SayHello]
--- Error message:
[Additional Information] If you are using SAML Client Policy and you see 'access denied' error, there could be two possible reasons:
(1) You may be trying to propagate the inbound subject on outbound, but there is no inbound subject. SAML Client policy needs a valid current user to create the appropriate SAML token. Make sure you have a valid inbound subject and the value of override 'subject.precedence' is TRUE.
(2) You may be trying to use an override to specify a static subject from CSF to generate the SAML token, but you have not granted appropriate permission to the OSB project that contains this business service. You need to add permissions to the system-jazn-data.xml in your domain through Oracle Enterprise Manager - Fusion Middleware Control. Make sure you have a valid CSF entry in override 'csf-key' and the value of override 'subject.precedence' is FALSE.
oracle.wsm.security.SecurityException: access denied (oracle.wsm.security.WSIdentityPermission resource=OSBExamplesProject assert)
at oracle.wsm.security.policy.scenario.util.PermissionUtil.checkIdentityPermission(PermissionUtil.java:83)
at oracle.wsm.security.policy.scenario.processor.WssSamlTokenProcessor.getUserNameWhenSubjectIgnoredAfterCheckingPermission(WssSamlTokenProcessor.java:535)
at oracle.wsm.security.policy.scenario.processor.WssSamlTokenProcessor.retrieveUserNameAndAttributesForSamlAssertionSubject(WssSamlTokenProcessor.java:402)
at oracle.wsm.security.policy.scenario.processor.WssSamlTokenProcessor.build(WssSamlTokenProcessor.java:231)
at oracle.wsm.security.policy.scenario.processor.WssSamlTokenProcessor.build(WssSamlTokenProcessor.java:204)
at oracle.wsm.security.policy.scenario.executor.Wss10SamlTokenScenarioExecutor.sendRequest(Wss10SamlTokenScenarioExecutor.java:127)
at oracle.wsm.security.policy.scenario.executor.SecurityScenarioExecutor.execute(SecurityScenarioExecutor.java:855)
at oracle.wsm.policyengine.impl.runtime.AssertionExecutor.execute(AssertionExecutor.java:41)
at oracle.wsm.policyengine.impl.runtime.WSPolicyRuntimeExecutor.executeSimpleAssertion(WSPolicyRuntimeExecutor.java:425)
at oracle.wsm.policyengine.impl.runtime.WSPolicyRuntimeExecutor.executeAndAssertion(WSPolicyRuntimeExecutor.java:344)
at oracle.wsm.policyengine.impl.runtime.WSPolicyRuntimeExecutor.execute(WSPolicyRuntimeExecutor.java:291)
at oracle.wsm.policyengine.impl.PolicyExecutionEngine.execute(PolicyExecutionEngine.java:102)
This error occurs because we have asked the proxy to switch the identity to the user specified in the CSF but the proxy does not have the security permission that allows it to perform this identity switch.
Enabling Identity Switching
In order to be able to use the CSF to specify the user to test as the proxy needs to be able to perform an identity switch. In order for this to occur the proxy, or more accurately the OSB project, must have permission to perform identity switching. This is accomplished by creating a system policy permission that enables identity switching through the Enterprise Manager console (it can also be scripted in WLST if required). The Oracle OSB documentation here is the starting point for the documentation around enabling identity switching.
In order to allow identity switching you must grant the OSB Project containing the OSB project the oracle.wsm.security.WSIdentityPermission
permission. The following procedure will enable the permission.
- Open the Enterprise Manager console in your browser, typically http://localhost:7001/em
- Expand the "WebLogic Domain" tree node and right-click the domain name to bring up the context window
- Select "Security/System Polcies" from the context menu
- Search for all "codebase" policies
- Select the first policy and click the "Create-Like" button
- In the "Codebase" field enter:
file:${common.components.home}/modules/oracle.wsm.agent.common_11.1.1/wsm-agent-core.jar
- In the Permissions list delete any existing permissions
- Add a permission by clicking on the "Add" button. Enter the following details into the "Edit Permission" overlay:
- Permission Class:
oracle.wsm.security.WSIdentityPermission
- Resource Name:
resource=<OSB Project Name>
- Permission Actions:
assert
- Permission Class:
- Click the "OK" button in "Create System Grant" screen to save the policy permission.
Testing as WebLogic User
Now that the OSB project has the correct permissions it should be possible to use CSF to specify the user "weblogic" and get the proxy to generate the correct SAML assertion.
Property | Override Value |
---|---|
subject.precedence | false |
csf-key | weblogic |
As seen in the following screenshot.
Now when the SOAP header is observed through the test console the SAML assertion contains "weblogic" as the username:
<soap:Header xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<wsse:Security soap:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<saml:Assertion MajorVersion="1" MinorVersion="1" AssertionID="SAML-BkdkFqlRMZ0TgRjyBkYMow22" IssueInstant="2014-04-23T09:56:23Z" Issuer="www.oracle.com" xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion">
<saml:Conditions NotBefore="2014-04-23T09:56:23Z" NotOnOrAfter="2014-04-23T10:01:23Z"/>
<saml:AuthenticationStatement AuthenticationInstant="2014-04-23T09:56:23Z" AuthenticationMethod="urn:oasis:names:tc:SAML:1.0:am:password">
<saml:Subject>
<saml:NameIdentifier Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified">weblogic</saml:NameIdentifier>
<saml:SubjectConfirmation>
<saml:ConfirmationMethod>urn:oasis:names:tc:SAML:1.0:cm:sender-vouches</saml:ConfirmationMethod>
</saml:SubjectConfirmation>
</saml:Subject>
</saml:AuthenticationStatement>
</saml:Assertion>
</wsse:Security>
</soap:Header>
Success! The OSB proxy can now be tested using a user stored in CSF as the identity asserted in the SAML token.
The example in this blog post uses a policy that does not enforce message integrity or message protection and therefore whilst suitable for testing purposes should not be used for a proper implementation. It is highly recommended that once successful testing has been achieved that a policy that enforces at least message integrity is employed as otherwise the SAML token can be easily spoofed.
Friday, 25 October 2013
OSB 11g: Testing OWSM with UsernameToken Policy (oracle/wss_username_token_service_policy)
OSB 11gR1 PS 7 (11.1.1.7) makes use of OWSM and one of the out of the box policies should enforce the use of UsernameToken, specifically the policy oracle/wss_username_token_service_policy. However there are a few additional steps that may need to be completed before this can be successfully tested. This article attempts to capture all of the steps.
Pre-requisites for OWSM
Firstly in order to use OWSM and its associated policies this must be enabled for the OSB domain. This is not the case by default and requires some additional configuration. Note also that the use of OWSM requires the use of a database.
1. Use the 11.1.1.7 Repository Creation Utility (RCU) to create a Database schema that the OSB domain will use. For OWSM the "Oracle AS Repository Components/AS Common Schemas/Metadata Services" schema is required however the Reporting Provider requires "Oracle AS Repository Components/SOA and BPM Infrastructure/SOA Infrastructure" schema and "Oracle AS Repository Components/SOA and BPM Infrastructure/User Messaging Service" schema
- "Oracle AS Repository Components/AS Common Schemas/Metadata Services"
2. The domain must be created or extended with the following product options:
- Oracle Service Bus OWSM Extension
- Oracle Enterprise Manager
- Either Oracle Service Bus for developers, or
- Oracle Service Bus
- WebLogic Adavanced Web Services for JAX-RPC Extension (required by OSB)
- Oracle WSM Policy Manager (recommended by OSB OWSM)
- Oracle JRF (required by OSB)
3. During the domain creation the OWSM MDS Schema must be configured to use the Database schema that was created with the RCU.
Applying the OWSM Policy
Assuming that the per-requisites for using OWSM have been met then it should be possible to select OWSM policies from the "Security" tab of the Proxy service that should use the policy.
Clicking the "Browse" button will bring up a new window which will list all the policies that have been registered with OWSM. Select the one named "oracle/wss_username_token_service_policy".
Ensure that the Proxy Service has been saved.
Testing the Secured Proxy
Before the OSB test console can be used for the selected "oracle/wss_username_token_service_policy" policy a test credential (in this case a user name and password) must be configured in the Credential Store Framework (CSF). The OSB test console uses CSF to locate the username and password it should supply to the service.Creating the Credential in CSF
To create the test user credential in the Credential Store Framework (CSF).
1. Open the Enterprise Manager Fusion Middleware Control (http://localhost:7001/em)
2. Navigate to the CSF page by performing the following:
a) Expand the WebLogic Domain.
b) Right Click on the domain and then select "Security/Credentials" from the resulting context menu.
3. Create the required credential.
a) Click the "Create Map" button and create a new map with the name "oracle.wsm.security". It has to be this name precisely and no other! If it already exists then this can be skipped.
b) Click the "Create Key" button and create a new key with the same name as your WebLogic administration user, typically "weblogic". Enter the following details and then click the "Ok" button:
Map = oracle.wsm.security
Type = Password
User Name = weblogic
Password = ****** (whatever your WebLogic user's password is)
Using the CSF Credential in the Test Console
Now that a user credential has been created in the CSF we can refer to that from the OSB test console when making a call to the secured proxy.
1. Launch the OSB test console. Right-click on the proxy within OEPE and select "Run on Server". This should launch the test console within the IDE.
2. Enter whatever data you require as the payload of the request.
3. Under the "Security" section of the page specify the csf-key property of "weblogic" (or whatever you setup as the key in the CSF).
You should see the Proxy Service testing result page and in the request there should be a UsernameToken that looks something like the following:
xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
Friday, 31 May 2013
Cloud Application Foundation. WebLogic - Your Caffeinated Choice!
If you are an active WebLogic practitioner then it is likely that you will have either already come across the term Cloud Application Foundation (CAF) or will do sometime soon. If you already understand what CAF is then congratulations - and you can skip this article! For the rest of us I thought I would peel back some of the marketing buzzwords and look at what CAF offers.
CAF is an Oracle product marketing term used to describe a sub-set of its middleware products that are frequently used as the basis for developing/deploying (and managing) applications, often providing software as a service (SaaS) - (read highly scalable) hence the "Cloud" moniker
The Cloud Application Foundation components are as follows (accurate at time of writing):
- Application Server
- Oracle WebLogic Server
- Oracle Tuxedo
- Oracle Glassfish Server
- Oracle Application Server
- Data Grid
- Oracle Coherence
- Management
- Oracle Enterprise Management
- Oracle Virtual Assembly Builder (OVAB)
- The Cloud Application Framework, hosted on the Oracle site.
- The Cloud Application Framework Blog, hosted on Oracle Blogs Site
Wednesday, 12 December 2012
WLST: Simplified Server Control
- userConfigFile - The path to the user config file. Refer to the storeUserConfig() WLST function for further information.
- userKeyFile - The path to the user key file. Refer to storeUserConfig() WLST function for further information.
- host - The listen address for the NodeManager. This is available in the domain configuration. We simply need to know which Machine definition we should reference. If we know which server we are interested in controlling then we can look up the associated Machine definition.
- port - the listen port for the NodeManager. Again this is available in the domain configuration and again we can use a reference to a Machine definition.
- domainName - The name for the domain. Again this is available in the domain configuration.
- domainDir - The directory for the domain. Ok we do need this one.
- nmType - The "type" of the NodeManager connection. Typically either "plain" or "ssl". This can be derived from the domain configuration. If a value has not been specified then the default of "ssl" should be assumed. Again we can use the reference to a Machine definition.
- verbose - Whether or not the NodeManager should use verbose messages. We will ignore this for our purposes and always assume a value of "false".
Therefore, assuming that we have access to the domain configuration in a given domain directory we should be able to derive many of the required parameters and simplify the nmConnect to be something a bit more user-friendly. We introduce a function nmConnectForServer which
nmConnectForServer(domainDir, serverName)
- domainDir - The directory containing the domain configuration.
- serverName - The name of the Managed Server whose Machine definition we want reference to determine our NodeManager connection parameters.
Once we have the WLST function we can flesh out a bit of a script that uses this function and takes appropriate arguments to allow us to control the server and view its status with the nmStart(), nmKill() and nmStatus() built-in WLST functions.
The script can then be invoked
wlst.sh nmServerControl.py start | stop | status
The advantages of this approach is that the domain configuration is used to determine the connection parameters rather then coding these parameters into a script or other configuration file. Should they change the start script will not have to be altered. Another advantage is the script becomes environment agnostic.
The following code defines such a WLST script:
# -----------------------------------------------------------------------------
# Control a WebLogic server with NodeManager
#
# @arg 1 action One of "start", "stop" or "status"
# @arg 2 domainDir Path to the domain directory
# @arg 3 serverName The name of the server to start
#
# -----------------------------------------------------------------------------
# Author: weblogically.blogspot.com
# Version: 1.0a
# Date: 18/07/2012
# Tested on: 11g PS5 11.1.1.5
# -----------------------------------------------------------------------------
# This WLST script controls servers by connecting to and issuing commands
# directly to the NodeManager. As such the NodeManager must be running but
# there is no requirement for the AdminServer to be running.
#
# The builtin WLST function 'nmConnect' requires parameters that are readily
# available in the domain configuration. This script provides an alternative
# function 'nmConnectForServer' which reads the domain to locate the specific
# parameters values for the given domain/server and passes these to nmConnect
# thereby significantly reducing the number of parameters that must be
# manually passed in to start a server.
#
# This does function requires that the domain directory to readable.
#
# This script does not try to set the server start properties so the server
# should have been started via the AdminServer at least once beforehand. This
# should have created a server start properties file that will be then used.
#
# This script does require previously stored the security credentials in the
# appropriate config and key files (see storeUserConfig)
# -----------------------------------------------------------------------------
import sys
# @function: nmConnectForServer
#
# Connects to the NodeManager associated with the specified NodeManager
#
# @param domainDir The path to the domain directory
# @param serverName The name of the server
#
def nmConnectForServer(domainDir, serverName):
readDomain(domainDir)
domainName=get("Name")
cd("/Server/" + serverName)
machineName = get("Machine").getName()
cd ("/Machine/" + machineName + "/NodeManager/" + machineName)
nmListenAddress = get("ListenAddress")
nmListenPort = get("ListenPort")
nmType = get("NMType")
if nmType == None:
nmType = "SSL"
closeDomain()
nmConnect(
userConfigFile=domainDir + "/nm-userconfig.properties",
userKeyFile=domainDir + "/nm-userKey.properties",
host=nmListenAddress,
port=nmListenPort,
domainName=domainName,
domainDir=domainDir,
nmType=nmType,
verbose="false")
#
# @function: nmStartServer
#
# Convenience function that connects to NM and asks it to start the server
#
# @param domainDir The path to the domain directory
# @param serverName The name of the server
#
def nmStartServer(domainDir, serverName):
nmConnectForServer(domainDir, serverName)
nmStart(
serverName=serverName,
domainDir=domainDir)
nmDisconnect()
#
# @function: nmStopServer
#
# Convenience function that connects to NM and asks it to stop the server
#
# @param domainDir The path to the domain directory
# @param serverName The name of the server
#
def nmStopServer(domainDir, serverName):
nmConnectForServer(domainDir, serverName)
nmKill(
serverName=serverName)
nmDisconnect()
#
# @function: nmStatusServer
#
# Convenience function that connects to NM and asks it for the status of the
# server
#
# @param domainDir The path to the domain directory
# @param serverName The name of the server
#
def nmStatusServer(domainDir, serverName):
nmConnectForServer(domainDir, serverName)
nmServerStatus(
serverName=serverName)
nmDisconnect()
#
# @function: printUsage
#
# Print the usage pattern for this script
#
# @param domainDir The path to the domain directory
# @param serverName The name of the server
#
def printUsage():
print "Usage: weblogic.WLST " + sys.argv[0] + " start|stop|status <domainDir> <serverName>"
# hostname = java.net.InetAddress.getLocalHost().getHostName()
# -----------------------------------------------------------------------------
# MAIN
# -----------------------------------------------------------------------------
try:
if len(sys.argv) < 4:
printUsage()
exit("y", 1)
else:
if "start" == sys.argv[1]:
nmStartServer(sys.argv[2], sys.argv[3])
elif "stop" == sys.argv[1]:
nmStopServer(sys.argv[2], sys.argv[3])
elif "status" == sys.argv[1]:
nmStatusServer(sys.argv[2], sys.argv[3])
else:
print "Error: Unknown instruction"
printUsage()
exit("y", 1)
except:
print "An error occurred."
dumpStack()
raise
Wednesday, 1 August 2012
WLST: Password Prompt
To get a handle on the Console object we get it from the System object:
We can then invoke the readPassword method. The readPassword method takes as arguments a format string and number of var args. To simplify things we will use a format string that just outputs the first var arg as a string and then pass the prompt in as the first var arg. Jython will interpret the var args as a list so we initialize a list containing the single value which is the prompt :
The final piece of the puzzle is that the readPassword method returns char[]. We want the password as a string value. The Python String object has a join method that will work for this purpose:
And that's it. All of this can be truncated into the following:
There may be other methods for getting a password, but this works and assuming WLST is invoked from a JDK which is at version 6 (1.6) or greater should be quite portable and not require any other Python packages.
Monday, 23 April 2012
OSB 11g: Patching OSB on Windows 7 with OPatch
1. Start a Command window with Administrator priviledges
Administrator priviledges are required in order for the OPatch utility to get the appropriate locks on the files that are used by the OPatch utility. To initiate the Command window with Administrative priviledges right-click the icon that you use to start the Command window and select "Run as administrator" from the resulting context menu. This should launch the Command window.
2. Set the ORACLE_HOME environment variable
The ORACLE_HOME environment variable needs to be set within the context of the new Command window. This should be set to the OSB_HOME, typically this
3. Navigate to the directory in which you have unzipped the patch to be applied.
cd PATH_TO_PATCH_DIR
4. Run the OPatch utility to apply the patch.
The OPatch utility can be used to apply the patch with the command:
opatch apply -jdk JDK_HOME
The OPatch utility is available from the OSB_HOME. As we have already set the ORACLE_HOME environment variable to this location we can use this variable to launch the OPatch script. You need to provide the JDK and JRE location. The exact value for JDK and JRE locations will vary depending on the system and installation locations.
5. Confirm that the patch has been applied
The OPatch utility can be used to list any patches that have been applied with the following command:
Again, we can use the ORACLE_HOME environment variable to launch the OPatch utility
Possible Errors and Solutions
If you have followed the process above then you should not see these errors. They are included here for completeness.
Unable to lock Central Inventory
OiiolLogger.addFileHandler:Error while adding file handler - C:\Program Files (x86)\Oracle\Inventory/logs\OPatch2012-04-23_11-11-28-AM.log
java.io.FileNotFoundException: C:\Program Files (x86)\Oracle\Inventory\logs\OPat
ch2012-04-23_11-11-28-AM.log (Access is denied)
Unable to lock Central Inventory. OPatch will attempt to re-lock.
Do you want to proceed? [y|n]
n
User Responded with: N
Unable to lock Central Inventory. Stop trying per user-request?
OPatchSession cannot load inventory for the given Oracle Home C:\oracle\middlewa
re\Oracle_OSB1. Possible causes are:
No read or write permission to ORACLE_HOME/.patch_storage
Central Inventory is locked by another OUI instance
No read permission to Central Inventory
The lock file exists in ORACLE_HOME/.patch_storage
The Oracle Home does not exist in Central Inventory
ApplySession failed: ApplySession failed to prepare the system. Unable to lock C
entral Inventory. Stop trying per user-request?
System intact, OPatch will not attempt to restore the system
OPatch failed with error code = 73
Solution: Run the command window with Administrator priviledges.
The Oracle Home is not OUI based home
If the ORACLE_HOME environment variable is not set then attempting to run the OPatch utility will result in the error message:
Solution: Set the ORACLE_HOME to be the OSB_HOME (Oracle_OSB1)