Recently I got the request to provide JMS Queues monitoring access to a group of users with the privileges to view and manage de messages in the queues. This can be done through the WebLogic console but for this customer, all is done via ansible scripts. Thus I had to find a scripting solution.

I followed the Oracle documentation to create the policy.

Extract of the WLST code:

try:
   print "applying JMS access policy for domain", domainName
   xacmlFile = open('XACMLAuthorizer.xml','r')
   xacmlDoc = xacmlFile.read()
   print(xacmlDoc)
   print "cd('/SecurityConfiguration/" + domainName + "/DefaultRealm/myrealm/Authorizers/XACMLAuthorizer')"
   cd('/SecurityConfiguration/' + domainName + '/DefaultRealm/myrealm/Authorizers/XACMLAuthorizer')
   print "add policy"
   cmo.addPolicy(xacmlDoc)
   print "done applying policy"
   return True
except Exception, inst:
   print inst
   print sys.exc_info()[0]
   dumpStack()
   sys.stderr.write("unable to apply JMS access policy for domain " + domainName)
   return False

The XACMLAuthorizer.xml policy file:

<?xml version="1.0" encoding="UTF-8"?>
<Policy PolicyId="urn:bea:xacml:2.0:entitlement:resource:type@E@Fjmx@G@M@Ooperation@Einvoke@M@Oapplication@E@M@OmbeanType@Eweblogic.management.runtime.JMSDestinationRuntimeMBean" RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable">
  <Description>Rol(Admin,MonitorJMSQueues)type=&lt;jmx&gt;, operation=invoke, application=, mbeanType=weblogic.management.runtime.JMSDestinationRuntimeMBean</AttributeValue>
          <ResourceAttributeDesignator AttributeId="urn:oasis:names:tc:xacml:2.0:resource:resource-ancestor-or-self" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/>
        </ResourceMatch>
      </Resource>
    </Resources>
  </Target>
  <Rule RuleId="primary-rule" Effect="Permit">
    <Condition>
      <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-at-least-one-member-of">
        <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-bag">
          <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Admin</AttributeValue>
          <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">MonitorJMSQueues</AttributeValue>
        </Apply>
        <SubjectAttributeDesignator AttributeId="urn:oasis:names:tc:xacml:2.0:subject:role" DataType="http://www.w3.org/2001/XMLSchema#string"/>
      </Apply>
    </Condition>
  </Rule>
  <Rule RuleId="deny-rule" Effect="Deny"/>
</Policy>

The script works fine but I get the following error when trying to see the messages stored in the JMS Queue.


<Administration Console encountered the following error:
weblogic.management.NoAccessRuntimeException: Access not allowed for subject:
principals=[<LIST-OF-PRINCIPALS],
on Resource weblogic.management.runtime.JMSDestinationRuntimeMBeanOperation: invoke , Target: getMessages
at weblogic.rmi.internal.ServerRequest.sendReceive(ServerRequest.java:295)
at weblogic.rmi.internal.BasicRemoteRef.invoke(BasicRemoteRef.java:299)
at javax.management.remote.rmi.RMIConnectionImpl_12214_WLStub.invoke(UnknownSource)
at javax.management.remote.rmi.RMIConnector$RemoteMBeanServerConnection.invoke(RMIConnector.java:1020)
at sun.reflect.GeneratedMethodAccessor154.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at weblogic.management.remote.wlx.ClientProvider$WLXRMIConnectorWrapper$1$1.call(ClientProvider.java:715)
at weblogic.invocation.ComponentInvocationContextManager._runAs(ComponentInvocationContextManager.java:287)
at weblogic.invocation.ComponentInvocationContextManager.runAs(ComponentInvocationContextManager.java:272)
at weblogic.management.remote.wlx.ClientProvider$WLXRMIConnectorWrapper$1.invoke(ClientProvider.java:709)
at com.sun.proxy.$Proxy115.invoke(Unknown Source)
at sun.reflect.GeneratedMethodAccessor154.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at weblogic.management.remote.wlx.ClientProvider$WLXRMIConnectorWrapper$1$1.call(ClientProvider.java:715)
at weblogic.invocation.ComponentInvocationContextManager._runAs(ComponentInvocationContextManager.java:287)
...

The policy was not applied until I go to the WebLogic console and save the policy following the steps below:

  • – Under Security Realms -> “Roles and Policies” -> Realm Policies, in the Policy table, select “JMX Policy Editor.”
    – Select “Global Scope” and click Next.
    – From MBean Types, open “weblogic.management.runtime”
    – Select “JMSDestinationRuntimeMBean” and click next.
    – In Attributes and Operations, select the View edit link for the “Operations: Permission to Invoke.”
  • There I see the policy created with the WLST script. If I click on the save button, then the policy works.

    The documentation doesn’t tell it but there a setPolicyExpression call needed after the addPolicy. This to apply the loaded policy.

    try:
       print "applying JMS access policy for domain", domainName
       xacmlFile = open('XACMLAuthorizer.xml','r')
       xacmlDoc = xacmlFile.read()
       print(xacmlDoc)
       print "cd('/SecurityConfiguration/" + domainName + "/DefaultRealm/myrealm/Authorizers/XACMLAuthorizer')"
       cd('/SecurityConfiguration/' + domainName + '/DefaultRealm/myrealm/Authorizers/XACMLAuthorizer')
       print "add policy"
       cmo.addPolicy(xacmlDoc)
       print "Applying policy done"
       cmo.setPolicyExpression('type=<jmx>','{Rol(Admin) | Rol(MonitorJMSQueues)}')
       print "Set policy done"
       return True
    except Exception, inst:
       print inst
       print sys.exc_info()[0]
       dumpStack()
       sys.stderr.write("unable to apply JMS access policy for domain " + domainName)
       return False
    

    After this, the users or groups of users having the roles MonitorJMSQueues and Monitor assigned are able to monitor the the JMS queues and manage the messages in them.