While the main thread impersonates a client, my code creates a thread and assigns it the impersonation token using SetThreadToken. Then the main thread closes the token.
Specifically, the main thread does this:
Get a primary token using LogonUser.
Get an impersonation token using DuplicateToken from the primary token.
Call ImpersonateLoggedOnUser.
Spawn a secondary thread and call SetThreadToken on the thread with the impersonation token.
RevertToSelf.
CloseHandle on both the impersonation and the primary token.
At this point, the secondary thread is still running. Does the impersonation token remain usable for the secondary thread even though the token handle has been closed in the main thread?
windows kernel use reference counting on objects. the TOKEN is object too. when you assign token to thread (via SetThreadToken) the pointer to TOKEN object is stored in ETHREAD object and additional reference added to TOKEN object. of course kernel cannot rely on close you or not original handle (reference) to TOKEN object. this is general pointer counting rule - if A stored pointer to B in self - it add reference to B, for it will be valid until A use B. the token will be valid until your thread not impersonate another token, or end impersonation or exit. anyway after you assign token to thread you can close handle to it - token remain valid
if exist interest, how internal SetThreadToken work:
SetThreadToken call NtSetInformationThread with ThreadImpersonationToken information class. from kernel side implementation called PsAssignImpersonationToken - this api declared in ntifs.h. it implementation call PsImpersonateClient which and reference the passed token. as result it become valid util assigned to thread
The server thread could already be impersonating a client when
PsImpersonateClient is called. If this is the case, the reference
count on the token representing that client is decremented.
but anyway - we not need for this internal knowledge - need general think understand - object reference counting. if pointer to token saved in thread - this token of course must be valid until used by thread. as result it referenced. when thread stop using this token (change pointer or exit) - token dereferenced
Related
Let's say I have a contract function that expects a certain amount of near to be send with a certain transaction, the function is called create_order, create_order takes a couple arguments.
I have my contract setup in the frontend under the name myContract.
I want to call myContract.create_order({...}) but the transaction fails because this method call doesn't have the right amount of NEAR tokens attached.
How do I assign a certain value of deposit to a transaction?
It's possible to use account.functionCall directly (without sugar for RPCs) to either attach amount or specify gas allowance for the call.
See Account#functionCall in nearlib.
Nearlib supports it using account.functionCall(..., amount). But it might not work, because of the design of the access keys with function calls. Default authorized access keys towards applications only allows function calls without attached token deposits (only prepaid gas). It's done this way to prevent apps from automatically using your balance without your explicit approval. Details on access keys are here: https://github.com/nearprotocol/NEPs/blob/master/text/0005-access-keys.md
The way to attach a deposit for the transaction should be done with the explicit approval from the wallet. The app should create a request for the wallet, redirect to the wallet for the approval (or through the popup). Once user approves the transaction, it's signed with full access key from the wallet directly and broadcasted. But I'm afraid we don't have this API on the wallet yet. Issue for this: https://github.com/nearprotocol/near-wallet/issues/56
AFAIK it is not supported at the moment. It will be available after this NEP https://github.com/nearprotocol/NEPs/pull/13 lands.
I need to call a Rest API ONCE to get a SAML Token to use in the Authorization Header for all other Thread Group/Users in my test. What is the preferred way of doing this? I can see where I can add a header manager and use the variables from there, but it looks like the variable is scoped to the thread group. I assume I can use a property. To make it simple I want one thread group that calls the api to get the token, so it will only call once set some property and all the other thread groups will use the property to get the SAML token. I am newbie so please be nice, it seems like this is a standard thing to do. My plan was a JSON Extractor and somehow use that to set a property.
The easier way is using JMeter Functions instead of Beanshell (moreover Beanshell scripting is a kind of performance anti-pattern). Also you don't need this 2nd "property to variable" conversion.
In 1st Thread Group use __setProperty() function in order to convert JMeter Variable into a property like
${__setProperty(token,${token},)}
In 2nd Thread Group use __P() function to get the token property value like
${__P(token,)}
In general using single SAML token for the multiple threads doesn't seem very good idea to me as normally different users should have different tokens and good load test needs to represent real life situations as close as possible. So I would recommend considering using single token per single virtual user. If you need to pass the tokens across thread groups you can go for Inter-Thread Communication Plugin, it is way easier, moreover you will have confidence that 2nd thread won't start until it receives the token from 1st thread.
I found these thread(s) that helped:
How to get value from property in BeanShell (jmeter)
Still not sure if this is the correct way, but it worked.
I called my REST API to get my Token
I Used a JSON extractor to get the Token
I Set a Global Property to hold my token using a Bean Shell Assertion
props.put("token", vars.get("token"));
In my other thread group I get the token from the property
String token = props.get("token");
vars.put("token",token );
In the HTTP Header Manager I get the token from local variable ${token}
This seems tedious, I am hoping there is better way.
We are using the ADAL Mac library to authenticate. When using this library we get a 300 error (AD_ERROR_CACHE_MULTIPLE_USERS) with the description:
The token cache store for this resource contains more than one user. Please set the 'userId' parameter to the one that will be used.
When does this happen? How should one handle this scenario?
Background
ADAL has a token cache for all access/refresh tokens on the device. The cache keys on things like the user, resource being requested, etc.
The app can get into a state in which there are multiple tokens in the cache for the same request. While these tokens may represent something some different information, the information provided in the token lookup request was ambiguous in some way. Simple example:
Cache
hash(userA,B,C) -> token pair 1
hash(userB,B,C) -> token pair 2
hash(userA,F,G) -> token pair 3
Lookup (AcquireTokenSilent)
So now we do an AcquireTokenSilent request (cache lookup). This request doesn't require every pivot of the cache. For example,
AcquireTokenSilent(B, C)
There's ambiguity in this request, it could map to token pair 1 or 2.
Handling this Error
So there's two workarounds at this point:
Provide more information in the same request.
You can do a new AcquireTokenSilent request providing some more information that allows ADAL to definitively pick a cache entry. In this case, ADAL needs a userId meaning your app would need to store or lookup this value and pass it in the request. In our example,
AcquireTokenSilent(userA, B, C)
Ignore the cache and start from scratch.
If you cannot retrieve the userId and have no way to recover, your app can perform an interactive authentication request and ask the end user to enter their credentials. If you have a valid token, this is an adverse experience as your users will need to sign in more than necessary. This would just be a standard AcquireToken request. From our example (there's no user to request,
AcquireToken(B, C)
I have a system which gives an access to the set of resources via access tokens. So when clients need to access some particular resource they ask for the token (one resource - one token). I need to make one-off (or at least limited in time) token, to ensure even if tokens are leaked, they will soon become inactive.
What is the proper way to achieve that in CQRS based system? Querying the resource should not change the system state. In other words - we can't invalidate token in query handler. Can we?
These are different concerns. What I would do:
An edge check the authorisation (using the token provided) and
calls the query handler, together with the query/token info
Query returns the result
The edge publishes an event "TokenHasBeenUsed"
The edge returns the query result
Token provider consumes the event and invalidates the token.
You can also build it scheduling, invalidating the token after a while if not used. Plus, you can also have a usage counter or something and it all does not need to be blended to the edge or query handler.
I have a question about Spring MVC controllers scope and REST services. I have a couple of REST services, wich returns a token in the response so I can later recreate the state of the application, but I don't want the users use the same token twice, so I've decided to save an unique identifier inside the token and also in HttpServletRequest, so I can check it when I get the requests (a new identifier is generated in every request).
So, my questions are: 1) is there any other way to be sure that some user will not use the same token more than once (also considered to save that identifier in DB, but I would have lot of queries to insert, delete, verify, etc).2) is it ok for the controller that receives the requests to be a singleton, or should it be prototype? (considering that the identifier is taken from session and I don't want to mix it between different sessions).
A few words on tokens that are valid only once
It's not possible to achieve it
without keeping the track of the tokens somewhere. This security schema require some trade-offs, deal with it.
Give the user a token and keep the track of it on server side, just like a white list:
When a token is issued, add it to the white list.
When a request comes to the server with a token, check the white list and:
If the token is valid, accept the request and remove the token from the white list.
If the token is invalid, refuse the request by returning a proper status code such as 403.
Also, consider assigning an expiration date to the token and refuse any request that comes to the server with an expired token.
Regarding your performance concerns: Bear in mind that premature optimization is the root of all evil. You shouldn't optimize until you have a performance problem and you have proven that the performance problem comes from the way you store your tokens. You could start storing the tokens in the database and then consider a cache in memory, for example. But always be careful when fixing a problem that you currently don't have.
Working with JWT
If you go for JWT, there are a few Java libraries to issue and validate JWT tokens such as:
jjwt
java-jwt
jose4j
The jti claim should be used to store the token identifier on the token. When validating the token, ensure that it's valid by checking the value of the jti claim against the token identifiers you have on server side.
For the token identifier you could use UUID. In Java, it's as simple as:
String uuid = UUID.randomUUID().toString();
Since HttpSession#getId() is unique, you can use it to create an unique token:
// pseudo code
String token = httpSession.getId() + "-" + System.currentTimeMillis();
You can also create your own counter.
Here my two techniques to prevent it
Disable submit button:
We can disable submit button right before our function call HTTP request and enable it again after finish gets HTTP response. This technique is effective for the process that takes a long time to finish (more than 5 sec.). The user can not click n’ click again because of impatience to get the result. Additionally, we may show a loading box for a good experience.
Issue request token/id:
This technique actually more complicated and difficult to implement, but thanks to a good framework (such as Spring Boot) to make this easier. Before we are going to the code implementation, let’s talk about the mechanism first;
When form page is loaded, issue a new requestId
put issued requestId to HTTP header before calling the backend service
backend service identify a requestId is already registered or not
if requestId is already registered then we can mark as a violation request