Thursday, July 9, 2009

OPSS Sample Application


Over the past few weeks, I'd been working with the development team on putting together a nice OPSS Sample Application

The README gives a lot of detail about what the application does and how to use it, so I wanted to spend a little time here to point out some of the ways that existing WLS secured applications can be enhanced with OPSS and also some of the finer points on the application itself.

OPSS provides some good simple user profile services. Admittedly not as elaborate as something like an OIM would provide, but probably cleaner and easier to implement then going through the MBeanReader interfaces of WLS. Also, unlike the MBean interfaces in WLS, there is more than just users and groups. There's user and group attributes. In the sample application this is all very nicely wired to the embedded LDAP that ships with WLS, but through simple configuration can be changed to work with an enterprise repository (LDAP).

If you look at the initialize method of the LdapIdStore class inside of the LdapDC project, you see the set-up of the JPSContextFactory, JPSContext, and IdentityStore instances. The IdentityStore is essentially a handle the the AuthenticationProvider configured in WLS. In the same project, you'll also find the LdapIdStoreView class. This class demonstrates how to get a handle to the UserManager and RoleManager classes. These classes give you access to the users and enterprise roles defined in the application. The FMW Security Guide has all of the details

In the sample application, there are three enterprise roles - basic user, premium user and ezshareadmin. Notice that the sample application also comes pre-configured with a list of users assigned to those roles. This was all done from JDeveloper and packages as part of the application. When the application is deployed, the information is published into WebLogic Server's authentication provider - the embedded LDAP. For building applications, this can simplify and speed testing. All of the user, group, policy information etc. is stored in the jazn-data.xml, and as I mentioned can be edited from inside of JDeveloper.


In general, I'm not a huge fan of the Java 2 security model, but I think that the way that the CredentialStoreFramework (CSF) uses it in this example is reasonable. Basically, all of the encryption/decryption of the files is done with a symmetric key. Any code that can gain access to that key can access the messages. By using Java 2 permissions model, and having to explicitly grant code access to the key, this restricts the access to only authorized code. This is very useful in centralized environments where many applications are hosted in a single server. In the sample application all of the code is granted access for simplicity, but could be further restricted depending on requirements. This model also breaks the cycle of having to have the password to something...for example, keys are stored in a Java Keystore require a cleartext password to get the private key, but then where do you store that password? Prompt for it at start-up? Java 2 security provides the answer.

I also like the way that the sample application implements accessing the credential store. All of the access is centralized through two methods in the CryptoUtil class. This class can be found in the ezShareModel project. The key thing is that it uses PriviledgedAction to access the store.


This greatly simplifies the configuration of the Java 2 permissions since only the CryptoUtil.class has to be granted access, regardless of whatever other code is in the call stack.

I personally think the coolest part of the sample application is the way that the encryption and decryption is integrated into the ADF View Object. I'm constantly getting questions about data security - mostly around authorization - but this is another key requirement - confidentiality of data on disk. This can be achieved using features of the database, but what this solution shows is a clever way to do it from the middleware. If you look at the BasicFilesView.xml and BasicFilesViewRowImpl.java also in the ezShareModel project, you'll see that the view is using a custom row implementation, and that implementation in-turn is using the CryptoUtil class for all of its encryption/decryption. Very nice!

People can definitely post their questions here about the sample application or maybe suggest some use cases for extending the application....maybe Web Services security...interesting SSO or authorization scenarios. Let me know.

21 comments:

  1. Hi.

    I was able to get this to work prior to upgrading jdeveloper to PS1 (11.1.1.2.0). Now afrLoop continues to loop.

    I did notice after upgrading that I was receiving an error with regards to the provisioned users' passwords, which I resolved via the weblogic console.

    Thanks.
    http://forums.oracle.com/forums/thread.jspa?messageID=3970858#3970858

    ReplyDelete
  2. Hi,

    How I can get programmatically dependency structure between Application and Enterprise roles? In my case, on runtime, I need to know those Enterprise roles, which owns specific Application role. Is it possible?

    Thanks,
    Andrejus

    ReplyDelete
  3. Andrejus, Thanks for this very useful use case. How would this work in SSO scenario? I.E. an authenticated session on Server A requests a service on Server B ?

    ReplyDelete
  4. Hi,

    Link to OPSS sample application is broken,can you please fix it or let me know where i can get the sample application.

    Thanks
    RB

    ReplyDelete
  5. Fixed. URL is http://www.oracle.com/technology/products/id_mgmt/opss/samples/ezshare.zip

    JB

    ReplyDelete
  6. Hi! The application works very nice! I was wondering if I can deploy this application on two separate WLS servers (on separate machines) and setup SSO between them? (Perhaps via SAML or something). I've managed to point both applications to one single database, so I see the same data in both applications, but I don't know how to setup SSO between them.. Could you please help? I've tried to use this http://biemond.blogspot.com/2009/09/sso-with-weblogic-1031-and-saml2.html, but it still does not do SSO :-( Thanks very much for any help! BTW. I'm using WLS 10.3.2

    ReplyDelete
  7. Hi,
    I would like to know the step-by-step process to create the sample application like ezshare especially LDAP integration with ADF pages.

    Thanks,
    Vengala Reddy

    ReplyDelete
  8. Josh, I'm having trouble with the link:

    http://www.oracle.com/technology/products/id_mgmt/opss/samples/ezshare.zip

    I'm logged into Oracle, but every time I try the link above, I get redirected to:

    http://www.oracle.com/technetwork/middleware/id-mgmt/overview/index.html

    ReplyDelete
  9. Hi Josh,

    it seems link is broken , is there a way to download sample application

    ReplyDelete
  10. Naresh,

    That link is indeed gone on OTN. However, you can still find the code by searching OTN for the file "ezshare.zip".

    Also, we are working on putting this code into a project on samplecode.oracle.com.

    Thanks,

    Brian

    ReplyDelete
  11. You should be able to get the code from https://opss_sample_code.samplecode.oracle.com/ now.

    ReplyDelete
  12. Hi,
    I also found a link for downloading the sample
    http://www.oracle.com/technetwork/testcontent/ezshare-131779.zip
    Is it the same sample?

    Thanx in advance.

    ReplyDelete
  13. Hi Josh,

    Would the OPSS API let me programatically map enterprise roles and groups to application roles?

    Many thanks,
    Laurence.

    ReplyDelete
  14. Hey there Lawrence!

    Yes, there is an API for it. Take a look:
    http://opss.us.oracle.com/javadoc/FMW_PS5/public/oracle/security/jps/service/policystore/PolicyMgmt.html

    Andre.

    ReplyDelete
  15. Lawrence, sorry, you're actually looking for

    http://opss.us.oracle.com/javadoc/FMW_PS5/public/oracle/security/jps/service/policystore/PolicyStoreUtil.html#addPrincipalToAppRole(java.lang.String, java.security.Principal, java.lang.String)

    Andre.

    ReplyDelete
  16. Since the one I've just sent has been deprecated, use this one:

    http://opss.us.oracle.com/javadoc/FMW_PS5/public/oracle/security/jps/service/policystore/ApplicationPolicy.html#addPrincipalToAppRole(java.security.Principal, java.lang.String)

    Andre.

    ReplyDelete
    Replies
    1. Hi Andre,

      I am not able to get the above link.Can u let me know where I can get this.

      Manohar

      Delete
    2. HEre you go: http://docs.oracle.com/cd/E12839_01/doc.1111/e14650/toc.htm

      Delete
  17. That's fantastic, Andre. Thank you very much indeed.

    I'll investigate this week and report anything I think useful to the blog.

    Please keep writing articles!

    Regards,
    Laurence.

    ReplyDelete
  18. Hi,

    Do you know a way to reset user password via OPSS, without knowing the original password?

    The only method provided in the API's is oracle.security.idm.UserProfile.setPassword(char[] oldpw, char[] newpw)

    Currently I'm trying to retrieve the password from the CredentialStore, but I'm probably using the wrong map and/or key....

    AccessController.doPrivileged(new PrivilegedExceptionAction[gt]Object[lt]() {
    public Object run() throws CredentialInvalidException, CredStoreException, JpsException, IMException {
    CredentialStore cStore = JpsContextFactory.getContextFactory().getContext().getServiceInstance(CredentialStore.class);
    PasswordCredential c = (PasswordCredential)cStore.getCredential("ezshare_map", user.getGUID());
    if (c != null) {
    String name = c.getName();
    char[] oldPassword = c.getPassword();
    System.out.println("name: " + name + ", password: " + oldPassword);

    //-- option 1
    user.getUserProfile().setPassword(oldPassword, "new_password".toCharArray());
    //-- option 2
    PasswordCredential credential = CredentialFactory.newPasswordCredential("basic1", "new_password".toCharArray());
    cStore.setCredential("ezshare_map", user.getGUID(), credential);

    return null;
    }
    }
    });

    ReplyDelete

Note: Only a member of this blog may post a comment.