Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
cancel
Showing results for 
Search instead for 
Did you mean: 
ekaterinamitova
Advisor
Advisor
14,408


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#<USER>#0##4D6D5E5E006011E5CB4400000093A95E#4d6d5e5e006011e5cb4400000093a95e##0#Thread[HTTPWorker [@1110872576],5,Dedicated_Application_Thread]#Plain##
User: <USER> has not enough permissions. For more details see the exception.
[EXCEPTION]
javax.jms.JMSSecurityException: User: <USER> has not permission: vpName: myVP, type: queue, action: produce, destination: MyQueue
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 at runtime.

 

What you can do to adjust your application?


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:


<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. However, make sure the relevant permissions are granted only to users who are expected to have these permissions.

  • 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/myVP/MyQueue");

QueueConnectionFactory queueConnectionFactory = (QueueConnectionFactory)context.lookup("jmsfactory/myVP/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)


When you create a new JMS destination, UME actions are also created.



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):




In the end


This JMS Security Mechanism helps you to protect your JMS application by defining JMS actions for some API methods (such as createProducer(), createConsumer(), and so on) and giving the possibility to assign these actions to different user roles. If you still have any concerns, list them in the comments section below.

6 Comments