Thursday, February 25, 2010

OID password policies and account lockouts

The other day I blogged about database 11g's default password policies and how to disable them for your test environment. Today my passwords for OID expired and I thought I'd pass along the same information for OID in case anyone anyone needs that information too.

The first thing you should know is that there is no oidadmin in OID 11g. I'm going to ignore the GUI tools here and just document how to disable the policies via ldapmodify.

First find your default password policy by searching for any objects with the objectclass of pwdpolicy. In the default configuration there should be only one
[oracle@demo5 ~]$ ldapsearch -b dc=oracledemo,dc=com -p 3060 -D cn=orcladmin -w abcd1234 objectclass=pwdpolicy dn
cn=default,cn=pwdPolicies,cn=Common,cn=Products,cn=OracleContext,dc=oracledemo,dc=com
[oracle@demo5 ~]$
Assuming you want to disable the policy all you need to do is change the value of pwdlockout to 0 (that's Zero, not Oh) and the policy will be disabled. So something like this:
[oracle@demo5 ~]$ ldapmodify -p 3060 -D cn=orcladmin -w abcd1234
dn: cn=default,cn=pwdPolicies,cn=Common,cn=Products,cn=OracleContext,dc=oracledemo,dc=com
changetype:modify
replace: pwdlockout
pwdlockout: 0

modifying entry cn=default,cn=pwdPolicies,cn=Common,cn=Products,cn=OracleContext,dc=oracledemo,dc=com

[oracle@demo5 ~]$
And finally if you have any accounts that are locked out and you need them re-enabled without changing their password you need to modify the account and add the attribute orclpwdaccountunlock with the value 1 (that's one, not El). So something like this:
[oracle@demo5 ~]$ ldapmodify -p 3060 -D cn=orcladmin -w abcd1234
dn: uid=hbowman,cn=Users, dc=oracledemo, dc=com
changetype: modify
add: orclpwdaccountunlock
orclpwdaccountunlock: 1

modifying entry uid=hbowman,cn=Users, dc=oracledemo, dc=com

[oracle@demo5 ~]$

Tuesday, February 23, 2010

Oracle database 11g default password policies

I recently booted a VM that I hadn't used in some time and found this error appeared when I fired up sqlplus
ERROR:
ORA-28002: the password will expire within 7 days
From what I've been able to gather Oracle database 11g sets up a password expiration policy by default. This isn't usually a problem for me since I usually create a VM, work on it for a week or six before moving on to another project. But this VM is special - it's my combined IAM stack demo VM from OpenWorld and I need it every once in a while.

If you find yourself in this position here's how you disable the password policies and get things working again.
First turn off the password policies:
ALTER PROFILE DEFAULT LIMIT
FAILED_LOGIN_ATTEMPTS UNLIMITED
PASSWORD_LIFE_TIME UNLIMITED
PASSWORD_GRACE_TIME UNLIMITED;
Then check the status of your accounts:
set line 120
select username, account_status, expiry_date, lock_date from dba_users;
Then reenable the ods user and any other users by resetting their password:
alter user ods identified by abcd1234;
Hope this helps!

Remember: Don't do this in production!

Monday, February 22, 2010

OpenAz PEP Layer Now Available

The PEP layer is now available for the OpenAz project. You can find some very basic information on it here. I spent a decent amount of time working with the XACML guys on this layer. What I wanted to try to do was built a set of APIs that simplified building PEPs on top of the AzAPI (Java wrapper around XACML). The AzAPI, like XACML is very very powerful, but in the work that I do with customers, most of the time, customers are looking for some basic functionality. Based on patterns we've seen at a number of customers, we tried to make some very common PEP scenarios easy to implement with the this layer. In this post, I'll show how the OpenAz PEP simplifies building a PEP.

The Hello World PEP



AzService azService = new org.openliberty.openaz.pdp.provider.SimpleConcreteService();
PepRequestFactory pep = new PepRequestFactory(CONTAINER,azService);
PepRequest req = pep.newPepRequest("josh","hello","world");
PepResponse resp = req.decide();
System.out.println(resp.allowed());

if (resp.allowed()) {

Map<String,Obligation> obligations = resp.getObligations();
Iterator obligationsIt = obligations.keySet().iterator();
while (obligationsIt.hasNext()) {
String obligationName = obligationsIt.next();
Map values = obligations.get(obligationName);
System.out.println(obligationName+"=>"+values);
}
}

The org.openliberty.openaz.pdp.provider.SimpleConcreteService is the example AzService (wrapper around XACML) that is there in the OpenAz project. Soon, we'll get an implementation of the AzService that uses the Sun XACML implementation.. Using the AzService we get a handle to the PEPRequestFactory. The PEPRequestFactory is used to generate one a PEPRequests. In the example, we're using the most basic for - simply passing in a String for the user, the action, and the resource. Once the request is generated, a response is returned and we can process the result. The response has a simple yes/no result, and then a handle to process the obligations. Obligations, as we've discussed on numerous occasions on this blog, can be used to have the PDP communicate additional responses to the PEP.

Features of the PEP Layer


The example above shows how simple doing very basic PEP calls, but there are a number of powerful features that are worth highlighting
  • Mapping of Native Java Objects - You can create a PEP request from any Java Object. This is done through the concept of "mappers". Each PEPequestFactory is configured with a set of Mappers. A mapper converts a Java object into a collection of attributes that XACML PDP can understand. This means that things like JAAS Subjects, Java Permissions, String, Sockets, custom objects, can be marshalled from their native form to XACML. Very useful is you want nice clean code.
  • Simplified Response Handling - As you saw in the example, the response is a simple yes/no and the Obligations are basically strings.
  • Handlers - You can add pre and post decision handlers to extend the functionality with caching (pre) or auditing (post).
  • Easy access to the full AzAPI - The main idea was to keep things simple at the PEP layer, but if implementations require the full AzAPI, you can start with the PEP layer, and the complete it by getting access to the AzRequestContext or AzResponseContext

    What should I do next?


    You can join the OpenAz mailing list, to follow and add to the discussion. Take a look at the project or sourceforge and contribute, or just give feedback on the API. A good place to start is with the tests. This shows some of the basic useage of the API.
  • Oracle Entitlements Server (OES) Advanced Rules Engine Like Capabilities

    Over the past week, I've had a couple of customers looking to use Oracle Entitlements Server (OES) to replace existing home grown authorization solutions that make heavy use of general purpose rules engines. As part of their investigation, I've gotten a few questions which basically boil down to "How to replicate the functionality that I have today in OES?". Before I get into the specific scenarios and how they can be achieved with OES, I want to make a some-what obvious point. OES is a rules-engine but its optimized to answer the "What Roles does this user have?" and "Can this user perform this action on this resource?" very quickly and efficiently. This means that getting OES to function exactly the same way as a generic rules engine functions can be done, but it will take custom code and probably complicate the policy model. The more fidelity required with the existing model the more complex the OES deployment. At some limit, it might just make sense to have OES call the rules engine via a custom eval function. This is an extreme case, and I mention it only to illustrate the point that when purchasing a product which replaces another product or custom solution, you'll get the best ROI by embracing the new products capabilities. Its in this context that I want to explore two specific scenarios.

    Named Rules


    The concept here is that a policy is just a combination of named rules. For example:

    Rule A: user has title="Manager"
    Rule B: user has department="12345"
    GRANT Role Manager_12345 if A and B

    There are a couple of different approaches for how to model this type of scenario in OES.

    Model Named Rules as Dynamic Attributes


    In this approach, the logic of the specific rules is "hard coded" into the attribute retriever. One nice thing about the AttributeRetrieverV2 interface is that you can get access to attributes via other AttributeRetrievers. Below is psuedocode for Rule A and Rule B

    package namedrules;

    import com.bea.security.providers.authorization.asi.*;
    import com.bea.security.providers.authorization.asi.ARME.evaluator.RequestHandle;

    import com.bea.security.providers.authorization.asi.ARME.exceptions.ArmeRuntimeException;
    import com.bea.security.providers.authorization.asi.ARME.exceptions.CredvarException;
    import com.bea.security.providers.authorization.asi.ARME.exceptions.NotReadyException;
    import com.bea.security.quark.exceptions.ParserException;

    import com.wles.BadParameterException;
    import com.wles.util.AttributeElement;

    import java.util.List;
    import java.util.Map;

    import javax.security.auth.Subject;

    import weblogic.security.service.ContextHandler;
    import weblogic.security.spi.Resource;

    public class NamedRuleAttributeRetriever implements AttributeRetrieverV2 {

    public String[] getHandledAttributeNames() {
    return new String [] {"RuleA","RuleB"};
    }

    public Object getAttributeValue(String name, RequestHandle requestHandle,
    Subject subject, Map map,
    Resource resource,
    ContextHandler contextHandler) {

    if (name.equals("RuleA")) {
    try {
    AttributeElement title = requestHandle.getAttribute("title",true);
    List titleValues = (List)title.getValueAs(List.class);
    return titleValues.contains("Manager");
    } catch (Exception e) {
    e.printStackTrace();
    return Boolean.FALSE;
    }
    } else if (name.equals("RuleB")) {
    try {
    AttributeElement dept = requestHandle.getAttribute("department",true);
    List deptValues = (List)dept.getValueAs(List.class);
    return deptValues.contains("12345");
    } catch (Exception e) {
    e.printStackTrace();
    return Boolean.FALSE;
    }

    }

    }
    }

    The biggest downside to this approach is that the rules themselves are hard coded inside of the logic of the attribute retriever. If this logic changes, you need to recode the retriever and re-deploy. It would better to have something a little more generic.

    Model Named Rules as Resources


    The idea is that the actual logic of the rule membership is still modeled in OES policy, instead of in the code. To do this create a separate node in the same SM called "namedrules". Model the rules like this:

    GRANT (//priv/RuleA, //app/policy/namedrules, //sgrp/users/allusers) if sys_defined(title) and title="manager"
    GRANT (//priv/RuleB, //app/policy/namedrules, //sgrp/users/allusers) if
    sys_defined(dept) and dept="12345"

    Now, the trick part. How do I get these policies evaluated? You'll need to make a call back into the AuthorizationService. This is pretty powerful, yet some what risky stuff. The issue is that you don't want to wind up with circular dependencies that will cause StackOverflow. The best way to avoid this is to not have named rules referencing named rules. If you need to be more fancy, then the example below could be extended to include a ThreadLocal variable with a counter to make sure that you're not putting more than say 5 requests on the stack. Below is the basics for this type of approach.

    package namedrules;

    import com.bea.security.AccessResult;
    import com.bea.security.AppContext;
    import com.bea.security.AppContextElement;
    import com.bea.security.AuthenticIdentity;
    import com.bea.security.AuthenticationService;
    import com.bea.security.AuthorizationService;
    import com.bea.security.ParameterException;
    import com.bea.security.PolicyDomain;
    import com.bea.security.RuntimeAction;
    import com.bea.security.RuntimeResource;
    import com.bea.security.SecurityRuntime;
    import com.bea.security.ServiceNotAvailableException;
    import com.bea.security.ServiceType;
    import com.bea.security.SimpleContextElement;
    import com.bea.security.providers.authorization.asi.ARME.evaluator.RequestHandle;
    import com.bea.security.providers.authorization.asi.AttributeRetrieverV2;

    import java.util.Map;

    import javax.security.auth.Subject;

    import weblogic.security.service.ContextElement;
    import weblogic.security.service.ContextHandler;
    import weblogic.security.spi.Resource;

    public class PolicyBasedAttributeRetriever implements AttributeRetrieverV2{

    private AuthorizationService atz;
    private AuthenticationService auth;
    private PolicyDomain pd;

    public PolicyBasedAttributeRetriever() {
    super();
    }

    public String[] getHandledAttributeNames() {
    return new String[]{};
    }

    public Object getAttributeValue(String ruleName, RequestHandle requestHandle,
    Subject subject, Map map,
    Resource resource,
    final ContextHandler contextHandler) {


    if (atz==null) {
    try {
    pd = SecurityRuntime.getInstance().getPolicyDomain(System.getProperty("wles.realm"));
    this.auth = (AuthenticationService)pd.getService(ServiceType.AUTHENTICATION);
    this.atz = (AuthorizationService)pd.getService(ServiceType.AUTHORIZATION);
    } catch (Exception e) {
    e.printStackTrace();
    return null;
    }
    }

    try {
    AuthenticIdentity ai = this.auth.assertIdentity("WLS.Subject",subject);

    RuntimeResource runtimeResource = new RuntimeResource("namedrules","exampleResource");
    RuntimeAction runtimeAction = new RuntimeAction(ruleName, "exampleAction");

    //This is just a simple wrapper around the ContextHandler
    AppContext contextHandlerWrapper = new AppContext() {

    public int size() {
    return contextHandler.size();
    }

    public String[] getNames() {
    return contextHandler.getNames();
    }

    public AppContextElement getElement(String name) {
    return new SimpleContextElement(name,contextHandler.getValue(name));
    }

    public AppContextElement[] getElements(String[] strings) {

    ContextElement [] ctxElements = contextHandler.getValues(strings);

    AppContextElement [] appCtxElements = new AppContextElement[ctxElements.length];

    for (int i=0; i<ctxElements.length; i++) {

    appCtxElements[i] = new SimpleContextElement(ctxElements[i].getName(),ctxElements[i].getValue());

    }

    return appCtxElements;
    }
    };

    AccessResult result =
    this.atz.isAccessAllowed(ai,runtimeResource,runtimeAction,contextHandlerWrapper);

    return Boolean.valueOf(result.isAllowed());

    } catch (Exception e) {

    return Boolean.FALSE;
    }

    }
    }

    A few key things in the example. You'll need to use a lazy initialization of the PolicyDomain. If you try to load it in the constructor of the AttributeRetriever, bad things happen. Also, using the built in WLS.Subject token type for the IdentityAsserter is an easy way to convert from a JAAS Subject to an AuthenticIdentity.

    Rule Debug Information


    Another scenario is that the caller needs to understand very detailed information about the rules evaluation. Some examples

    • Why did the user did not get access?
    • What role cause the user to get access?

    OES has a number of ways of addressing these types of queries

    Add report_as to your policies


    The simplest thing to do is to add report_as constraint to a given policy. Note: This only works for authorization policies. An example:

    DENY (//priv/read, //app/policy/someresource, //role/authors) if NOT owner = sys_user and report_as("error","You are not the owner of this document")

    This works for a few policies, but may not be practical if you have a very large number of policies.

    Use DebugInfo


    If you are using the Java SM, you can use the DebugInfo to get very detailed information about which roles and rules applied. The instructions for using this Debug API are here. One observation that might make things easier. Through the entitlementsadministration ui you can add notes to policies. Those notes are available through the API. You can even get down to specific attributes and their values.

    Custom Evaluation Function


    This approach works for SMs other than the Java SM or if you want to report back additional information about policy evaluation and attributes. Take the example where a user is granted access based upon attributes.

    GRANT (//priv/read, //app/policy/r1, //sgrp/users/allusers/) if assertAttribute("state","=","CA",true,"You don't live in California") AND assertAttribute("txn_amount","<",500,true,"Transaction is over 500")

    The idea with this example is that I want to be able to communicate why the user is not granted access. Below is the psuedocode for the assertAttribute function.

    package namedrules;

    import com.bea.security.providers.authorization.asi.ARME.evaluator.RequestHandle;

    import com.wles.util.AttributeElement;

    import java.util.List;

    public class AttributeEvalFunction {


    public boolean assertAttribute (RequestHandle requestHandle, java.lang.Object[] args, javax.security.auth.Subject subject, java.util.Map roles, weblogic.security.spi.Resource resource, weblogic.security.service.ContextHandler contextHandler) {

    try {
    String attributeName = (String)args[0];
    String operator = (String)args[1];

    Boolean assertionResult = (Boolean)args[3];

    AttributeElement element = requestHandle.getAttribute(attributeName,true);

    boolean result = false;

    if (element.getASIType().equals("string")) {

    String value = (String)args[2];

    if (operator.equals("=")) {
    List values = (List)element.getValueAs(List.class);
    result = values.contains(value);
    }


    }

    if (assertionResult.booleanValue() == result) {
    System.out.println("Assertion Passed: "+attributeName+" "+operator+" "+args[2]+" "+assertionResult.booleanValue());
    return true;
    } else {
    //Return the message
    System.out.println("Assertion Failed: "+attributeName+" "+operator+" "+args[2]+" "+assertionResult.booleanValue());
    requestHandle.appendReturnData(attributeName,args[4]);
    return false;
    }

    } catch (Exception e) {
    e.printStackTrace();
    return false;
    }

    }

    }

    Conclusion


    This post outlines a number of ways to use the OES engine to emulate some common capabilities of generic rules engines. Its obviously some bit of work to select the right approach to fit specific requirements. Hopefully what I've show is helpful in bootstrapping some thinking in this area. I look forward to your feedback and some of your own patterns in this area.

    Wednesday, February 10, 2010

    A simple remote API that modifies WebLogic Portal (WLP) Visitor Entitlements

    Recently, I was looking for a simple remote API to modify the visitor entitlement roles available inside of a portal. Specifically, I wanted to check if a role existed, and if it didn't create it. The entire use case is that the role policies are going to be defined in Oracle Entitlements Server (OES) but the policy (assigning or roles to WLP artifacts like desktops and portlets) is going to be handled inside of WLP. We'll leave the OES pieces for another time. The focus on this post is the WLP APIs that are available for manipulating the visitor entitlements.

    After reviewing what I knew about WLP Vistor entitlements and scanning the documentation, I presented two approaches to the WLP team - direct modification of the database or some use of the RolePolicyManager. I was pushed towards the API approach - after all - that's what its there for. I was initially leaning towards the database because I wanted to invoke this API simply, and you can do quite a bit with SQL Ant Task. So, off I went to try to figure out how to use the RolePolicyManager.

    First of all, I'm not a WLP expert, so if this is a well know issue, then read on, but I had trouble getting Workshop to generate a valid WLP EAR. I had this problem - some issue with the facets being out of whack. Thanks gsmith.

    Moving on, now that I had an EAR, the next step was to figure out how to use the RolePolicyManager to search for a role. The first thing that helped was turning on some WLP debugging. I set-up a debug file file this:

    # turn on package names for debugging
    usePackageNames: on


    # append output to mydebug.log file rather than System.err
    out.file = mydebug.log

    com.bea.p13n.entitlements.management: on

    This dumps out a lot of good information. So, with debug on, and clicking through the WLP Visitor Entitlements screens, I get some output like this:

    [com.bea.p13n.entitlements.management.internal.RDBMSRolePolicyManager.getRolePolicy():347] get role policy:
    id: type=, EntApp=MyPortalEAR, Webapp=MyWeb, Resource=com_bea_p13n_role_policy_pool, Capability=
    policy name: AnonymousVisitor

    This lead to my first ah-ha! I was able to return the list of Roles for the web app by making the following API call

    out.println(java.util.Arrays.asList(RolePolicyManager.listRolesForResource(ear,war,"com_bea_p13n_role_policy_pool")));

    com_bea_p13n_role_policy_pool is the resource. The javadoc then tells me that the String [] returned contains role policy names.

    At this point, I'm almost there with all of the parameters that I need to create a RolePolicyItem and see if it exists. The only missing piece is the resourceScope. All of the likely values are available on EntitlementsConstant. After some experimenting, the answer is EntitlementConstants.ENT_APP_ROLE_INHERITANCE. I'm now able to check and see if a role policy exists.

    com.bea.p13n.entitlements.policy.RolePolicyItem ri =
    new com.bea.p13n.entitlements.policy.RolePolicyItem();

    ri.setEntAppName(ear);
    ri.setResourceId("com_bea_p13n_role_policy_pool");
    ri.setWebAppName(war);
    ri.setPolicyName(role);
    ri.setResourceScope(com.bea.p13n.entitlements.common.EntitlementConstants.ENT_APP_ROLE_INHERITANCE);


    com.bea.p13n.entitlements.policy.RolePolicyItem ri2 =
    rpm.getRolePolicy(ri);

    if (ri2==null) {

    rpm.createRolePolicy(ri);
    out.println("Role "+role+" added.");

    } else {

    out.println("Role "+role+" already exists");

    }


    If the role doesn't exist it returns null. All that's left is to create the role, and that's a line call. The next time the administrator logs into the portal administration - the role is there :)

    One problem that I had to overcome. I'd been invoking this from inside an unprotected JSP. When I go to call the getRolePolicy method, I get an exception that I'm not authorized. To work around this, I move the jsp to a folder called admin and protect that folder with BASIC auth and restrict access to only the role Admin which includes the user weblogic. From web.xml:



    Admin Resources
    /admin/*


    Admin



    Admin


    BASIC


    and weblogic.xml


    Admin




    So now I have a JSP packaged in a separate EAR that can add a role to any webapp in any ear deployed on the cluster. Also, by placing the JSP in a different WAR and protecting it by BASIC, its pretty simple to go an invoke it remotely. I used cURL


    I hope that this post helps other people who need a simple remote API for manipulating the WLP Visitor Entitlements. The techniques discussed (as well as actually looking at the p13 schema) should give you enough information to extend this approach to other operations and scenarios.