In the example provided on the IS4 website for calling a web API (the function CallApiUsingUserAccessToken), it creates at each request a HTTP client. I read on the web that you can run into problems if too many requests are received by the server using this method.
Is any way we can declare static the http client and assign the bearer token somehow differently ?
If I declare static httpclient and use SetBearerToken extension, theoretically my token can be used by a subsequent request.
If you want to use a shared HttpClient, you need to create the HttpRequestMessage yourself and set the header on each message.
Then use the SendAsync method to send your message.
https://msdn.microsoft.com/en-us/library/hh138176(v=vs.118).aspx
Related
I am moving my app from Svelte SPA (original) to Sveltekit multi page app (new).
In the original app, I configure a http client up top and put it context using:
setContext(HTTP_CLIENT, httpClient)
Now the entire app can get that http client using
const httpClient = getContext(HTTP_CLIENT)
I do this because my app can be started with debug parameters than turn on http request logging.
I'm not clear how to do similar in Sveltekit, because it seems that pages do not share a context.
I tried sticking the http client in the session like this:
import { session } from "$app/stores";
$session.httpClient = httpClient
and I got:
Error: Failed to serialize session data: Cannot stringify arbitrary non-POJOs
So $session is meant to be serialized, ok. Does that mean that I need to put whatever debug parameters a user supplied in $session, and each page needs to freshly instantiate its own http client? Or is there some other idiomatic sveltekit way of doing this?
PS I know sveltekit has its own fetch so you might want to say "don't use your own http client", but my app uses many different service objects (graphql client for example) that can be configured in debug (and other) modes, so please don't zero in on the fact that my example is a http client.
One way around this could be to send down the configuration in the top __layout file, create the http client there and store in a store. Since stores are shared across all pages the client can then freely use this store.
I'm going through the following security tutorial and it configures a CsrfTokenRepository like this:
.csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
Is that all that is required to get Ajax requests working across all libraries? The Angular documentation for $http says that Angular reads the CSRF cookie that Spring provides and sets a corresponding a header when it makes requests. So I'm assuming it does this because the cookie will not automatically be included when sending Ajax requests?
[Update]
I read the article again and it says that the CSRF protection is provided by the header. So if I interpret that the right way it's the fact that the client is sending back the cookie value in a unique way that is different than it was sent in the first place that provides the CSRF protection. In other words the client receives the cookie and changes the way it is sent back, so that the server knows that the client is indeed in control of the cookie?
CSRF protection with Spring CookieCsrfTokenRepository works as follows:
Client makes a GET request to Server (Spring backend), e.g. request for the main page
Spring sends the response for GET request along with Set-cookie header which contains securely generated XSRF Token
Browser sets the cookie with XSRF Token
While sending state changing request (e.g. POST) the client (Angular) copies the cookie value to the HTTP request header
The request is sent with both header and cookie (browser attaches the cookie automaticaly)
Spring compares the header and the cookie values, if they are the same the request is accepted, otherwise 403 is returned to the client
Note that only state changing requests (POST, PUT, DELETE) are CSRF protected by default and only these need to be protected when API is properly designed (i.e. GET requests don't have side effects and modify the state of the app for example).
The method withHttpOnlyFalse allows angular to read XSRF cookie. Make sure that Angular makes XHR request with withCreddentials flag set to true.
I read a lot about Spring Securitys CSRF protection, but i still struggle a little bit. Now the documentation is great as usual, but it's completely based on the idea that you render html code on the server and are able to add a hidden field to every form. Now since i use AngularJS and JavaScript to call the backend this is not really an option.
So what is the best way to actually get the Token to the client in this case (Rest Backend / AngularJS frontend)? AngularJS seems to have built in support for CSRF in $resource and expects a Cookie called "XSRF-TOKEN" to retrieve the Token and send it as http header "X-XSRF-TOKEN" in further requests. So every request will contain the http header, as well as the cookie. Now on server side i could read the header and compare it to the Token i stored in the session.
The problem i have with this, it that it seems a bit complicated. Since the login itself has to be protected it would require creating a temporary session, just for the CSRF token. Is this really necessary?
Maybe this is just a stupid question, but why can't i just create a random-token on client side and set it as HTTP header and cookie on client side. This would be similar to "OWASP double submit cookie", but generate the Token on client-side. That way the server would not require to have a session before login, since he could just compare the 2 submitted tokens. Now while the attacker could send the HTTP header, he would per same-origin-policy have no way of reading or setting the cookie and could not get a match as long as the number is practically unguessable.
Now instinctly generating a secure token on client side seems dangerous to me and i guess i coul avoid it.. but WHY? I feel like i am missed something, surely there is a good reason why SpringSecurity stores the token in the session, right?
Please enlighten me :)
I ended up using spring-security-csrf-token-interceptor-extended, which reads the CSRF-Token from the http-header "X-CSRF-TOKEN" (name is configurable) and sends it as http-header on further requests.
Now the only thing i had to to was getting Spring-Security to send the Token as HTTP Header (since i don't render html code on serverside and therefor can't add it as a hidden field).
<security:http ....
<security:custom-filter ref="csrfTokenResponseHeaderBindingFilter" after="CSRF_FILTER"/>
....
</security:http>
The filter basically runs after the normal CSRF_FILTER and reads the "_csrf" request-attribute (which is put there by CSRF_FILTER) and sets it as header "X-CSRF-TOKEN"
public class CsrfTokenResponseHeaderBindingFilter extends OncePerRequestFilter {
protected static final String REQUEST_ATTRIBUTE_NAME = "_csrf";
protected static final String RESPONSE_TOKEN_NAME = "X-CSRF-TOKEN";
#Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, javax.servlet.FilterChain filterChain) throws ServletException, IOException {
CsrfToken token = (CsrfToken) request.getAttribute(REQUEST_ATTRIBUTE_NAME);
if (token != null) {
response.setHeader(RESPONSE_TOKEN_NAME, token.getToken());
}
filterChain.doFilter(request, response);
}
}
Now I just get and post Firebase request through sending https request using C language.
Is there any way to use callback for this?
Because I want to get the latest data, now I just polling the https get requests. The SSL handshake may cause delay, so I want to add callback for this.
I have an Apache camel application which talks with a web service. This is purely a integration(mediation) application. We take REST request and transform it to a SOAP message (using VM templates) and call the web service. Receive response from web service, transform it to JSON and send back to our client.
REST ---->transform to SOAP req (Velocity template) ---->call WS ---->receive response---->transform into JSON---->return response to caller.
We are using servlet endpoint to receive request from our client. We can obtain HttpSession object from exchange before calling web service as follows :
HttpServletRequest req = exchange.getIn().getBody(HttpServletRequest.class);
HttpSession session = req.getSession();
However, the problem is that I cannot obtain HTTPSession from exchange after receiving response from web service. If I check the Exchange object in debug mode, the Exchange.getIn() is of type DefaultMessage rather than HttpMessage. That is the reason I think I loose Request and response objects.
I tried setting the exchange pattern to InOut but that doesn’t help.
The only solution I could find is to store the original body of the in message in a header or a property and retrieve it at the end. But I think there must be a better solution that this.
Could anybody help please?
Note: We need HttpSession so that we can store corresponding session information like session id created on WS for the session created by our request. We cannot pass session information created on WS to our callers, and need a place on our application to hold this mapping info. HttpSession serves this requirement. Is there any better way?
You can store the http session as an exchange property, camel copy these properties across the exchanges, so you can access it in the route when you need.