| My Oracle & Java Blog

Wednesday, October 3, 2012

Error validating the certificate chain in Weblogic

We recently stumbled upon an odd problem configuring outgoing SSL connection from weblogic, to a remote web service.    After properly configuring the keystore with the right set of certificates to trust, we turned on SSL debugging (-Dssl.debug=true -Dweblogic.StdoutDebugEnabled=true -Djavax.net.debug=ssl,handshake,verbose), which yielded a little more detail in the error message:

Certificate chain is invalid because the issuer DN does not match the next certificate subject

A careful examination of the error messages showed that weblogic was trying to process the cerificate chain in the wrong order.   It started with "myserver" certificate, then immediately went and checked the "root" certificate.   The issuer of "myserver" certificate was not the "root", instead it was an "intermediate" authority. So WL was expecting to see the "intermediate" cert as being next in the chain, but instead received the "root", giving the error above.   This could be a problem with how that certificate is configured on the remote host.  However it seems like most other client libraries are more forgiving, and don't consider this to be an error.   Examining the certificate for the URL at the browser level, everything looks fine.  And running command line tests to connect to the URL via java worked just fine too.   So it appears that the default JDK SSL libraries can handle this situation, but the weblogic libraries can not.   To work around this problem, we had to make the following setting change:

-Dweblogic.wsee.client.ssl.usejdk=true

That will update web service connections which use Oracle's client libraries (like ADF connections, etc) to use the Sun JDK SSL handler, instead of the weblogic one.
There are also settings within weblogic console for "Use JSSE SSL", but that did not seem to have any effect on the web service connections, which apparently use a different set of libraries to connect.   If you have other types of outgoing connections, and you run into this problem, you may need to set that flag as well.

Wednesday, September 14, 2011

Unable to log into OAM Console 11g after installation

We've recently run into a problem after a clean successful installation of Oracle Access Manager 11g (in both 11.1.1.3 and 11.1.1.5).   In the Admin Server log we see an OAMSSA-20005 and OAMSSA-2007 errors, ultimately caused by a NumberFormatException, in trying to process the URL for the web logic admin server.  The URL, listed in the error message is using an IPv6 style address, which OAM apparently can't handle.  This was confirmed by oracle support, as the OAM server is currently not certified to work with IPv6, though certain components(web gates, etc) are, according to these docs:

http://download.oracle.com/docs/cd/E21764_01/doc.1111/e14774/oam.htm#CFHFACHJ
http://www.oracle.com/technetwork/middleware/id-mgmt/identity-accessmgmt-11gr1certmatrix-161244.xls

To fix this problem, we were able to disable the Teredo Pseudo Interface adapter as shown here (we were running Windows 2008 R2):
http://www.bradt.org/km/questions/22/Teredo+IPv6+-+Information+and+Disabling

Monday, January 24, 2011

JDeveloper "cacert" keystore default password

I can never seem to remember it. Oracle uses "changeit" as the default password for JDeveloper installations and standalone OC4J instances.

Wednesday, December 1, 2010

Weblogic error creating a simple Web Service using UsernameToken security

Looks like there is a bug of sorts in JDeveloper's (11.1.1.3) "Create Client Proxy from Web Service Annotations" option, if you are using WS-Security policies.
It seems the WSDL it generates before creating the proxy code does NOT include the WS-Security policy information. Adding attachToWsdl=true in the Policy annotation does not help either.
This causes the client to not send security policy tokens (even if you set the UNTCredentialProvider info), resulting in this error message:

"Error on verifying message against security policy Error code:1000"

So if you are using JDeveloper to create a secured Web Service you will not be able right-click your Web Service and generate a client proxy. Instead, you will need run the Web Service in Web Logic, get the URL for your WSDL, ie: http://localhost:7101/context/webservice?WSDL.
This version of the WSDL correctly includes the policy information. Then you can use the File->New menu in jdeveloper to create your Client Proxy, providing that WSDL URL instead of the one JDeveloper tries to create from the annotations.

In my case, I was using the Wssp1.2-2007-Https-UsernameToken-Plain policy. So I also needed to enable SSL on the built in Web Logic instance. This was done by logging into the console (http://localhost:7101/console, weblogic/weblogic1 is the default logon), then navigating to the server SSL options and enabling the SSL port.
Then in my client code, I needed to make sure the web logic Dummy cert was trusted, that was done by setting this system property:

System.setProperty("weblogic.security.TrustKeyStore","DemoTrust");

That allowed me to pass the weblogic/weblogic1 username to the webservice for authentication.

Next up, figuring out how to configure Web Logic, or the Web Service to authenticate the username/password against OID....

Monday, February 1, 2010

Getting around the ldapsearch column width problem

It seems that ldapsearch is limited to returning it's output in just 80 chars. This is in accordance with the RFC specification written long ago for the ldap protocol, making it easier to work with terminal output. Some newer clients support optional operators like -T or -r to allow for unlmited columns ("no-wrap") , but it's not officially part of the specification, so most do not. Most notably, the ldapsearch provided as part of windows, and with all Oracle installations does not include any of these options. So this can be particularly frustrating to deal with. To get around this problem, you can do the following:

1. export your data to an ldif file using ldapsearch
2. Notice that in addition to limiting to 80 chars, the wrapped lines all include a 1-char space indent. This is how you can tell an actual new line, from a wrapped line (this is also in accordance with the spec, it's how ldapadd/ldapmodify know how to proccess the entries).
3. So knowing this, it's then very simple to use a tool that support carriage-return search and replace (like Ultra Edit), to replace the carriage return plus 1 space, with nothing. So in ultra edit search for "^p " (omit the quotes), to unwrap the lines.

This will put all your entries on one line each, making it much more readable and maintainable. The resulting file with the longer columns is still supported for import by ldapadd/ldapmodify. It's not pretty, but it works very well.

Tuesday, November 20, 2007

Querying the Portal tables for a list of Secured Items

This is useful in producing audit reports and during migrations. It will print a list of all the group privileges assigned to the various objects in portal (pages, items, etc). You can easily update this to include user privileges, although most of our privileges were granted to groups rather than users. This also includes an additional join (p.name=t.filename) that allows you to retrieve the values for some custom object types as well.

select p.object_type_name,p.owner,p.name,p.grantee_group_id,g.id,g.name group_name, p.privilege,t.id,t.masterthingid, t.itemtype,t.title,t.title_link,t.description,t.author,t.filename,t.creator,t.createdate,t.updator,t.updatedate,t.version
from portal.wwsec_sys_priv$ p, portal.wwsec_group$ g , portal.wwv_things t
where p.grantee_group_id=g.id
and g.name not in ('AUTHENTICATED_USERS','PORTAL_ADMINISTRATORS','DBA','PORTAL_DEVELOPERS')
and( p.name = t.filename or
(p.name LIKE t.siteid||'%'
and p.name LIKE '%'||to_char(t.masterthingid)
)
)
and t.iscurrentversion=1
order by p.object_type_name,t.itemtype, p.name, g.name

Tuesday, May 29, 2007

How to query OID for Locked, Disabled, & Expired Accounts

OID's password policy allows for passwords to expire, at which point a user's account is locked. There tends to be a lot of confusion around this, as most people assume that account expiration is the same thing. It's not.
Account expiration results in an account being disabled after the account expiration date. Password expiration results in a user being locked out, which requires the password be reset.
One reason for the confusion is OID/DAS doesnt have a good way of displaying password expriations, so it appears that accounts are being randomly locked for no reason. In order to query the password expriation, you have to actually query the underlying ODS database schema, because oracle doesn't expose the needed attributes via the OID LDAP interface.
Metalink note 329618.1 has some specific queries you can use for locked and expired accounts. This query uses some of that, plus it includes more standard ldap attributes, like orclActiveEndDate for account expirations, etc.
This query should return a comprehensive status for all accounts in OID and is very useful in troubleshooting password expiration/account lockout issues:


create or replace view oid_account_status_v as
SELECT
dn.rdn, dn.parentdn
, DECODE(pwd.attrval,'0','',DECODE(SIGN( TO_DATE(substr(at1.attrval,1,14),'yyyymmddhh24miss')-SYSDATE+(pwd.attrval/86400)) ,-1,'yes')) pwd_expired
, DECODE(pwd.attrval,'0','never',ROUND( TO_DATE(substr(at1.attrval,1,14),'yyyymmddhh24miss')-SYSDATE+(pwd.attrval/86400)) ) days_until_pwd_expiry
, ROUND(pwd.attrval/86400) expiry_policy_days
, TO_DATE(substr(at1.attrval,1,14),'yyyymmddhh24miss') pwdchangetime
, at2.attrval enabled
, DECODE(at3.attrval, null,null, at3.attrval,'yes') locked
, at3.attrval accountlockedtime
, at4.attrval account_expiry
, DECODE(at4.attrval,null,'never', TO_DATE(substr(at4.attrval,1,14),'yyyymmddhh24miss')-SYSDATE ) days_until_account_expiry

FROM
ods.ct_dn dn,
(select * from ods.ct_dn pwd_dn, ods.ds_attrstore pwd_at where pwd_dn.entryid = pwd_at.entryid and pwd_at.attrname='pwdmaxage' AND pwd_dn.rdn='cn=pwdpolicyentry') pwd,
(select * from ods.ds_attrstore where attrname = 'pwdchangedtime') at1,
(select * from ods.ds_attrstore where attrname = 'orclisenabled') at2,
(select * from ods.ds_attrstore where attrname = 'pwdaccountlockedtime' and attrkind='o') at3,
(select * from ods.ds_attrstore where attrname = 'orclactiveenddate') at4

WHERE
(INSTR(dn.parentdn,',cn=users,') > 0)
AND substr(pwd.parentdn,1,INSTR(pwd.parentdn,',cn=oraclecontext',1)) ||'cn=users,' = dn.parentdn
AND dn.entryid = at1.entryid(+)
AND dn.entryid = at2.entryid(+)
AND dn.entryid = at3.entryid(+)
AND dn.entryid = at4.entryid(+)