By all means I know the following is not possible, but it is occurring in one of our production environments:
SETUP
ESAPI 2.01
Main servlet filter setting and removing a current request thread local object:
try {
ESAPI.httpUtilities().setCurrentHTTP(request, response);
// filter logic ...
} catch (Exception e) {
LOG.error(Logger.SECURITY_FAILURE, "Error in ESAPI "
+ "security filter: " + e.getMessage(), e);
request.setAttribute("message", e.getMessage());
} finally {
ESAPI.clearCurrent();
}
all requests pass through this filter, and ESAPI.currentRequest() is used throughout the system.
Path A (http://server/path_a/)
goes through until it reaches method_a, this method is not accessible from path_b
Path B (http://server/path_b)
goes through until it reaches method_b, not accessible from path_a
Both of these paths go through the servlet filter (mapping "/*")
One of our error mails that I received suggests that path_a is throwing an error, which in turn initiates the error mail, in the mail code, the current request (via ESAPI.currentRequest()) is enumerated for request info.
PROBLEM
In the error mail, request info from path_a correlates with stacktrace info from method_b, to me this seems impossible as both run in separate threads.
QUESTION
How is this possible? I cannot re-create this locally, are their certain precautions I have to take other than setting and clearing the ThreadLocal? Can this be a problem with tomcat setup? I'm lost.
PS: code from the question has been simplified as the code base is to large for an example
Reading ESAPI code https://code.google.com/p/owasp-esapi-java/source/browse/trunk/src/main/java/org/owasp/esapi/reference/DefaultHTTPUtilities.java there are some questionable practices regarding thread local.
The biggest problem I'd say is it uses InheritableThreadLocal. If thread A spawns a thread B, B will inherit A's thread local value; however, when A then clears the thread local, it doesn't affect B, so B's inherited value will stay. ESAPI probably shouldn't use InheritableThreadLocal.
I can't say how this may produce the problem you see, without knowing more about threads in your app.
Related
I'm running an HL Fabric private network and submitting transactions to the ledger from a Java Application using Fabric-Java-Sdk.
Occasionally, like 1/10000 of the times, the Java application throws an exception when I'm submitting the transaction to the ledger, like the message below:
ERROR 196664 --- [ Thread-4] org.hyperledger.fabric.sdk.Channel
: Future completed exceptionally: sendTransaction
java.lang.IllegalArgumentException: The proposal responses have 2
inconsistent groups with 0 that are invalid. Expected all to be
consistent and none to be invalid. at
org.hyperledger.fabric.sdk.Channel.doSendTransaction(Channel.java:5574)
~[fabric-sdk-java-2.1.1.jar:na] at
org.hyperledger.fabric.sdk.Channel.sendTransaction(Channel.java:5533)
~[fabric-sdk-java-2.1.1.jar:na] at
org.hyperledger.fabric.gateway.impl.TransactionImpl.commitTransaction(TransactionImpl.java:138)
~[fabric-gateway-java-2.1.1.jar:na] at
org.hyperledger.fabric.gateway.impl.TransactionImpl.submit(TransactionImpl.java:96)
~[fabric-gateway-java-2.1.1.jar:na] at
org.hyperledger.fabric.gateway.impl.ContractImpl.submitTransaction(ContractImpl.java:50)
~[fabric-gateway-java-2.1.1.jar:na] at
com.apidemoblockchain.RepositoryDao.BaseFunctions.Implementations.PairTrustBaseFunction.sendTrustTransactionMessage(PairTrustBaseFunction.java:165)
~[classes/:na] at
com.apidemoblockchain.RepositoryDao.Implementations.PairTrustDataAccessRepository.run(PairTrustDataAccessRepository.java:79)
~[classes/:na] at java.base/java.lang.Thread.run(Thread.java:834)
~[na:na]
While my submitting method goes like this:
public void sendTrustTransactionMessage(Gateway gateway, Contract trustContract, String payload) throws TimeoutException, InterruptedException, InvalidArgumentException, TransactionException, ContractException {
// Prepare
checkIfChannelIsReady(gateway);
// Execute
trustContract.submitTransaction(getCreateTrustMethod(), payload);
}
I'm using a 4 org network with 2 peers each and I am using 3 channels, one for each chaincode DataType, in order to keep the things clean.
I think that the error coming from the Channel doesn't make sense because I am using the Contract to submit it...
Like I'm opening the gateway and then I keep it open for continuously submit the txs.
try (Gateway gateway = getBuilder(getTrustPeer()).connect()) {
Contract trustContract = gateway.getNetwork(getTrustChaincodeChannelName()).getContract(getTrustChaincodeId(), getTrustChaincodeName());
while (!terminateLoop) {
if (message) {
String payload = preparePayload();
sendTrustTransactionMessage(gateway, trustContract, payload);
}
...
wait();
}
...
}
EDIT:
After reading #bestbeforetoday advice, I've managed to catch the ContractException and analyze the logs. Still, I don't fully understand where might be the bug and, therefore, how to fix it.
I'll add 3 prints that I've taken to the ProposalResponses received in the exception and a comment after it.
ProposalResponses-1
ProposalResponses-2
ProposalResponses-3
So, in the first picture, I can see that 3 proposal responses were received at the exception and the exception cause message says:
"The proposal responses have 2 inconsistent groups with 0 that are invalid. Expected all to be consistent and none to be invalid."
In pictures, 2/3 is represented the content of those responses and I notice that there are 2 fields saving null value, namely "ProposalRespondePayload" and "timestamp_", however, I don't know if those are the "two groups" referred at the message cause of the exception.
Thanks in advance...
It seems that, while the endorsing peers all successfully endorsed your transaction proposal, those peer responses were not all byte-for-byte identical.
There are several things that might differ, including read/write sets or the value returned from the transaction function invocation. There are several reasons why differences might occur, including non-deterministic transaction function implementation, different transaction function behaviour between peers, or different ledger state at different peers.
To figure out what caused this specific failure you probably need to look at the peer responses to identify how they differ. You should be getting a ContractException thrown back from your transaction submit call, and this should allow you to access the proposal responses by calling e.getProposalResponses():
https://hyperledger.github.io/fabric-gateway-java/release-2.2/org/hyperledger/fabric/gateway/ContractException.html#getProposalResponses()
I try to read data from web-server, which situated at some URL.
In our company I use e-Commerce API, which works with the data from web-server.
To retrieve the data at first I need to make pool of the data from web-server.
To make the pool of data I need to configure connection.
One part from step "I need to configure connection" is function getSession(), which uses the Shiro api(org.apache.shiro.SecurityUtils)
so every time when I try to make connection with web-server and use the data from the web-server I become an Exception "Exception in thread "main" org.apache.shiro.UnavailableSecurityManagerException: No SecurityManager accessible to the calling code, either bound to the org.apache.shiro.util.ThreadContext or as a vm static singleton. This is an invalid application configuration."
Before writing this question I tried to look at logs and read about classes and problem, which describe there.
This all runs on Windows 10, Java 8, Payara Server(Glassfish), with EJBAPI and some e-Commerce API.
Import that I use
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.session.InvalidSessionException;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
at
ContentConfiguration conf = new ContentConfiguration(
getSessionId(),
Constant.ENTITYMODELL,
Constant.EMPTY,
context);
protected static Session getSession()
{
Subject subject = SecurityUtils.getSubject();
if(subject.isAuthenticated())
return subject.getSession();
else
return null;
}
Error Message
Exception in thread "main" org.apache.shiro.UnavailableSecurityManagerException: No SecurityManager accessible to the calling code, either bound to the org.apache.shiro.util.ThreadContext or as a vm static singleton. This is an invalid application configuration.
at org.apache.shiro.SecurityUtils.getSecurityManager(SecurityUtils.java:123)
at org.apache.shiro.subject.Subject$Builder.<init>(Subject.java:627)
at org.apache.shiro.SecurityUtils.getSubject(SecurityUtils.java:56)
at de.kolb.demo.data.ServiceLocator.getSessionId(ServiceLocator.java:15)
at de.kolb.demo.logic.CommonTest.getCommonData(CommonTest.java:32)
at de.kolb.demo.presentation.ContentDirector.main(ContentDirector.java:34)
I want to get answer which represent situation in my company, but a lot of principes, which i will to describe connect with common proplem in Shiro hub.
1.My problem connect with getSessionId() enter image description here
2.getSessionId() it's a function from company API. In this function i call org.apache.shiro.SecurityUtils.getSubject() enter
link description here
At this moment I thought about exception Message No SecurityManager accessible to the calling code.... Than I look at Shiro documentation here enter link description here. There i found, that every time when i use Aplication, which use authentication and autorisation i need to configure "SecurityManager" with "Realm" object.
4.It is a small instruction and detailed instruction present at shiro site enter link description here
This might be a simple problem, but I can't seem to find a good solution right now.
I've got:
OldApp - a Java application started from the command line (no web front here)
NewApp - a Java application with a REST api behind Apache
I want OldApp to call NewApp through its REST api and when NewApp is done, OldApp should continue.
My problem is that NewApp is doing a lot of stuff that might take a lot of time which in some cases causes a timeout in Apache, and then sends a 502 error to OldApp. The computations continue in NewApp, but OldApp does not know when NewApp is done.
One solution I thought of is fork a thread in NewApp and store some kind of ID for the API request, and return it to OldApp. Then OldApp could poll NewApp to see if the thread is done, and if so - continue. Otherwise - keep polling.
Are there any good design patterns for something like this? Am I complicating things? Any tips on how to think?
If NewApp is taking a long time, it should immediately return a 202 Accepted. The response should contain a Location header indicating where the user can go to look up the result when it's done, and an estimate of when the request will be done.
OldApp should wait until the estimate time is reached, then submit a new GET call to the location. The response from that GET will either be the expected data, or an entity with a new estimated time. OldApp can then try again at the later time, repeating until the expected data is available.
So The conversation might look like:
POST /widgets
response:
202 Accepted
Location: "http://server/v1/widgets/12345"
{
"estimatedAvailableAt": "<whenever>"
}
.
GET /widgets/12345
response:
200 OK
Location: "http://server/v1/widgets/12345"
{
"estimatedAvailableAt": "<wheneverElse>"
}
.
GET /widgets/12345
response:
200 OK
Location: "http://server/v1/widgets/12345"
{
"myProperty": "myValue",
...
}
Yes, that's exactly what people are doing with REST now. Because there no way to connect from server to client, client just polls very often. There also some improved method called "long polling", when connection between client and server has big timeout, and server send information back to connected client when it becomes available.
The question is on java and servlets ... So I would suggest looking at Servlet 3.0 asynchronous support.
Talking from a design perspective, you would need to return a 202 accepted with an Id and an URL to the job. The oldApp needs to check for the result of the operation using the URL.
The thread that you fork on the server needs to implement the Callable interface. I would also recommend using a thread pool for this. The GET url for the Job that was forked can check the Future object status and return it to the user.
I try to get a connection to multiple clients using the Sockets in Java. Everything seems to work, but the problem is, that the server just listens to the first client. If there are multiple clients, the server can send them all messages, but he can just listen to the messages that came from the first client. I tried this all out (I'm at this problem since yesterday). So I'm pretty sure, that the fault has to be in the class "ClientListener".
Explanation:
There is a List with clients (connection to communicate with Strings). In the GUI there is a list, where I can choose, with which client I'd like to communicate. If I change the client, the variable currentClient (int) switches to another number
networkClients is an ArrayList, where all the different connections are "stored".
The first connected client is exactly the same as the other clients, there is nothing special about him. He is called, when the variable currentClient is set to 0 (per default). The variable-switching is working. Like I said, all the clients give me a response if I send them an order, but just networkClients.get(0) is heard by the server (ClientListener).
class ClientListener implements Runnable {
String request;
#Override
public void run() {
try {
while (networkClients.size() < 1) {
Thread.sleep(1000);
}
//***I'm pretty sure, that the problem is in this line
while ((request = networkClients.get(currentClient).getCommunicationReader().readLine()) != null) {
//***
myFileList.add(new MyFile(request));
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
I hope someone can help me. I tried many things, but nothing worked.
EDIT: Like I wrote in the code example, is it possible that the while-loop isn't able to switch the number of "currentClient" (which is handled by another Thread)? I tested/simulated something similar in a testclass and the result was, that a while-loop of course can can update the state in it (meaning, that if a variable changes in the () of a while loop, it will of course be checked after every repeat).
You should take a look at multithreading.
Your server program should be made out of:
- The main thread
- A thread that handles new connections.
(Upon creating a new connection, start a new thread and pass the connection on to that thread)
- A thread for each connected client, listening to the each client separately
Take a look at some examples like: (1) (2)
I found the solution:
The Thread sits in the declared method I mentioned in the starting post (in the code snippet) and waits unlimited time for a new response of the client.
So changing the index of the list "networkClients" won't do anything, because nothing will happen there, until there is a new order sent by the client (which lets the thread go further).
So you need to implement an extra listener for each client.
Let me first provide some background information. If you don't care you can skip to the next paragraph. I wanted to use the DrEdit sample Java application which is integrated with Google Drive as the basis of my application. I need to refactor the code, though, because the original scenario assumed that the user would only access the application through the Drive and never directly. Currently when the latter happens, a RuntimeException is thrown which should not be the case in a normal flow.
Thanks to that issue I stumbled upon a difference between my local environment and the GAE which is manifested when the following code is run:
} catch (CredentialMediator.NoRefreshTokenException e) {
try {
resp.sendRedirect(e.getAuthorizationUrl());
} catch (IOException ioe) {
throw new RuntimeException("Failed to redirect user for authorization");
}
throw new RuntimeException("No refresh token found. Re-authorizing.");
}
When I run this application on GAE, the RuntimeException is thrown (I can see it in the logs) and the sendRedirect is also executed so I get to see the page that should be displayed.
However when I run the same application locally, I get the HTTP 500 error and the RuntimeException is displayed but the sendRedirect is ignored.
So far I haven't been successful in finding an explanation for this behaviour. I would like to know why this is the case and if there are settings that I can change in order to fully replicate the GAE environment locally.
This is how standard defines the sendRedirect(). It actually commits the response so after calling this method you should not be able to change or add to the response. However it does not define what happens if you trigger an exception after redirect.
Anyway, your code is ambiguous on purpose - you should not continue processing the request and throw exceptions after sending redirect. If you have any processing to do, then do it before redirect.
OTOH you should not rely on generic exception handling. Instead install a servlet filter that catches exceptions and return a proper user-readable or device-readable response.