Quantcast
Channel: SCN : Blog List - All Communities
Viewing all articles
Browse latest Browse all 2548

JMS Authorization Enhancement: Your AS Java is not broken, fix your JMS application

$
0
0

Did you recently notice an exception in the default trace? Or in the JMS application logs? I mean this kind of exception:

 

#2.0#2015 05 25 12:20:51:590#+0300#Error#com.sap.jms.server.sc.UMESecurityProvider#

#BC-JAS-JMS#jms#C0000A37426704CE00000000000072BC#9677150000000004#sap.com/JMSTestProject#com.sap.jms.server.sc.UMESecurityProvider#Guest#0##4D6D5E5E006011E5CB4400000093A95E#4d6d5e5e006011e5cb4400000093a95e##0#Thread[HTTPWorker [@1110872576],5,Dedicated_Application_Thread]#Plain##

The username: Guest has not enough permissions. For more details see the exception.

[EXCEPTION]

javax.jms.JMSSecurityException: User: [ZI1] Guest has not permission: vpName: default, type: queue, action: produce, destination: MDBTestQUEUE

  at com.sap.jms.server.sc.UMESecurityProvider.checkPermission(UMESecurityProvider.java:218)

  at com.sap.jms.server.sc.UMESecurityProvider.checkDestinationProducePermission(UMESecurityProvider.java:113)

  at com.sap.jms.server.JMSVirtualProviderProcessor.producerCreate(JMSVirtualProviderProcessor.java:546)

  at com.sap.jms.client.session.JMSSession.createProducer(JMSSession.java:607)

  at com.sap.jms.client.session.JMSQueueSession.createSender(JMSQueueSession.java:56)

  at com.sap.jms.test.TestServlet.sendAndReceiveMessage(TestServlet.java:73)

  at com.sap.jms.test.TestServlet.doGet(TestServlet.java:47)

  at javax.servlet.http.HttpServlet.service(HttpServlet.java:734)

  at javax.servlet.http.HttpServlet.service(HttpServlet.java:847)

  at com.sap.engine.services.servlets_jsp.server.Invokable.invoke(Invokable.java:152)

...

  at com.sap.engine.services.httpserver.server.rcm.RequestProcessorThread.run(RequestProcessorThread.java:56)

  at com.sap.engine.core.thread.execution.Executable.run(Executable.java:122)

  at com.sap.engine.core.thread.execution.Executable.run(Executable.java:101)

  at com.sap.engine.core.thread.execution.CentralExecutor$SingleThread.run(CentralExecutor.java:328)

 

If you have already found this exception, don’t worry. There is nothing wrong with your AS Java. Here is what happens, and what you can do about it.

Note:There is no problem during build time, the issues appears only runtime.


What has been changed?

The JMS authorization mechanism has been changed in order to provide a better protection for the JMS destinations (JMS Queues and Topics).

More details on defining security in JMS: http://help.sap.com/saphelp_nw73ehp1/helpdata/en/05/54e14a42634e76a602584cc892a0c7/frameset.htm

 

A historical reason

Before this enhancement, the security Role Everyone had by default permissions to execute JMS operations. This is what you could see in the Identity Management in the SAP NetWeaver Administrator:

 

jms_auth1.png

 

After this enhancement there are no JMS operations available for the role Everyone, and this is why you get the exception I already talked about.

 

What you can do to adjust your application to this enhancement?

There are a couple of things you can choose from:

  • Setting the necessary authorizations in the actions.xml file. You can do this by adding the following code Here is an example:

 

<BUSINESSSERVICE NAME="MyVirtualProvider">  <ACTION NAME="my_all_action">    <PERMISSION NAME="myVP.queue" VALUE="ALL:$:MyQueue" CLASS="com.sap.jms.server.service.impl.JMSDestinationPermission"/>  </ACTION>  <ACTION NAME="my_produce_action">    <PERMISSION NAME="myVP.queue" VALUE="produce:$:MyQueue" CLASS="com.sap.jms.server.service.impl.JMSDestinationPermission"/>  </ACTION>  <ROLE NAME="MyASJavaRole">    <ASSIGNEDACTION NAME="my_produce_action"/>  </ROLE></BUSINESSSERVICE>

 

Or you can manually assign Action to the Role in the SAP NetWeaver Administrator → Identity Management.

 

 

Anyway, make sure the relevant Role (for example, MyASJavaRole) is assigned to the Users who are accessing JMS.

 

  • Using the runAs mechanism. Here you have two options: using Subject.doAs() in the source code of the JMS application, or adding the necessary information in the Java EE deployment descriptors, such as web.xml, ejb-jar.xml.
    • Using Java EE deployment descriptors.
      1. If you use JMS in a Servlet, or a JSP you have to adjust the web.xml and the web-j2ee-engine.xml files.

web.xml

 

<web-app>  <servlet>    <servlet-name>...</servlet-name>    ...    <run-as>      <role-name>MyServletRole</role-name>    </run-as>  </servlet>  <security-role>    <role-name>MyServletRole</role-name>  </security-role></web-app>

web-j2ee-engine.xml

 

<web-j2ee-engine>    <security-role-map>        <role-name>MyServletRole</role-name>        <server-role-name>MyASJavaRole</server-role-name>    </security-role-map></web-j2ee-engine>

 

      1. If you use JMS in EJBs, you need to change the ejb-jar.xml and the ejb-j2ee-engine.xml files.

ejb-jar.xml

 

<ejb-jar>    <assembly-descriptor>        <security-role>            <role-name>MyEJBRole</role-name>        </security-role>    </assembly-descriptor></ejb-jar>

 

ejb-j2ee-engine.xml

 

<ejb-j2ee-engine>    <security-permission>        <security-role-map>            <role-name>MyEJBRole</role-name>            <server-role-name>MyASJavaRole</server-role-name>        </security-role-map>    </security-permission></ejb-j2ee-engine>

 

    • Using Subject.doAs() method. Here is an example:

PrivilegedExceptionAction codeToBeExecutedWithGivenUser = new PrivilegedExceptionAction() {

  public Object run() throws Exception {

    //code to be executed with given user

    return null;

  }

};

 

 

IUser doAsUser = UMFactory.getUserFactory().getUserByLogonID("RUN_AS_USER");

 

// create new Subject

final Subject runAsSubject = new Subject();

runAsSubject.getPrincipals().add(doAsUser);

try {

    Object result = Subject.doAs(runAsSubject, codeToBeExecutedWithGivenUser);

} catch (PrivilegedActionException pae) {

    ...

}

 

  • Using the JMSConnectionFactory.createConnection(user, password) method in the source code of your JMS application. Here is an example:

 

InitialContext context = new InitialContext();

Connection con = null;

try {

    Queue queue = (Queue) context.lookup("jmsqueues/default/myQueue");

    QueueConnectionFactory queueConnectionFactory = (QueueConnectionFactory)context.lookup("jmsfactory/default/QueueConnectionFactory");

    con= queueConnectionFactory.createConnection(“User”, “Password”);

    Session session = con.createSession(false, Session.AUTO_ACKNOWLEDGE);

    QueueSender sender = (QueueSender) session.createProducer(queue);

    …

 

JMS destinations created manually in SAP NetWeaver Administrator (JMS Server Configuration plug-in)

If until now you have created JMS destinations, such as JMS queues and JMS topics, in the SAP NetWeaver Administrator, probably you have expected that everyone should be able to work with these destinations. From now on, this is not the case anymore. When you create a new JMS destination, UME actions are also created.

 

jms_auth2.png

If you want particular Users to be able to work with this JMS destination, you have to assign this action to a particular Role (which is assigned to the target Users):

 

jms_auth3.png

jms_auth4.png

In the end

This JMS Security enhancement should help you provide a better protection to the JMS Queues and Topics and therefore to your JMS application. If you still have any concerns, list them below in the comments section.


Viewing all articles
Browse latest Browse all 2548

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>