Can WCF REST (WebHttpBinding) honor PROGRAMMATIC outputcache policies? - wcf

I know all about the AspNetCacheProfileAttribute. But is there any way to hook into the cache programmatically? I've tried using Response.Cache in global.asax which seems to set the correct client-side headers but the response is never cached on the server.

I don't think you can do it unless you build your own solution. I just checked implementation of AspNetCahceProfileAttribute which only add internal CachingParameterInspector to the operation dispatcher. This has two problems:
Parameter inspector is assigned when the service host starts = during first request and until that it cannot be changed
Parameter inspector is initialized in its cosntructor by reading cache configuration from the web.config file based on the profile name passed to AspNetCacheProfileAttribute
There is no API available to modify already assigned and configured parameter inspector

Related

How to update options in Restsharp v107 (RestClientOptoins)

I'm not finding any RestClient method to update its options, what I need to do is for example disable FollowRedirects for certain requests.
How do I do the following but with v107?
client.FollowRedirects = false;
Background: maybe a separate issue but current problem is that RestSharp is not following a redirect URL to Okta from a Location header of a response, it goes to the main Client URL instead. That is why I've decided to disable redirects to try following the redirect manually.
Most if not all of the properties in RestClientOptions are used to configure the HttpMessageHandler instance wrapped by RestClient. As each RestClient instance wraps a single HttpClient (and its handler), those options cannot be changed. It works the same way as configuring HttpClient, where you cannot change the AllowAutoRedirects property of the handler once it's configured.
That's why the documentation suggests using a specifically configured RestClient instance per remote API. Normally, the API uses a single convention and configuration requirement.
I have seen that some authentication endpoints require redirects, but most of the time the RestClient instance used to get the authorization token is not the one used to access the API itself with the retrieved token. So, the solution would be to have a separate instance for that purpose. Normally, it's only used once to get the token, then you can dispose it and reuse the token.
I keep posting the authenticator example from the docs https://restsharp.dev/usage.html#authenticator
Concerning RestSharp not following redirects properly, it's not what RestSharp does as it doesn't compose or execute HTTP calls physically. It just wraps HttpClient.

Does ASP.NET Core handle pre-flight requests even without CORS being added as a middleware

I'm reading the book API Security in Action by Neil Madden. In the book, there is a section about CORS and how to attach the proper headers in Java. I am aware that there is already an AddCors and UseCors built in to ASP.NET Core, but for my edification I wanted to roll my own middleware.
However, I found that I was unable to receive any sort of OPTIONS requests, they were automatically being rejected somehow, and I was unable to respond to them manually, even when it was the first middleware in the pipeline. Since the UseCors middleware is able to intercept these pre-flight requests, I'm curious whether or not it is hooking into a deeper level of ASP.NET Core than I am able to.
TL;DR: Is ASP.NET Core (or Kestrel) performing some sort of automatic preflight request checking even when UseCors is not called?
The answer in the end is no, ASP.NET does not do anything fancy when it comes to preflight requests. I looked into the source code and the CorsMiddleware (and associated extensions) are relatively simple; most of the logic is contained within the ICorsService, and doesn't impact the middleware pipeline directly.
I'm unsure what my original issue was being caused by, but it is now resolved.
See below for the source code:
https://github.com/dotnet/aspnetcore/blob/a450cb69b5e4549f5515cdb057a68771f56cefd7/src/Middleware/CORS/src/Infrastructure/CorsMiddleware.cs
It is worth noting that if you add the CORS headers manually, you will get the following exception
System.InvalidOperationException: Endpoint ProjectName.Controllers.SomeController.Login (ProjectName) contains CORS metadata, but a middleware was not found that supports CORS.
Configure your application startup by adding app.UseCors() inside the call to Configure(..) in the application startup code. The call to app.UseCors() must appear between app.UseRouting() and app.UseEndpoints(...).
You can avoid this error by setting a flag to true in the custom CORS handler
httpContext.Items["__CorsMiddlewareWithEndpointInvoked"] = true;
However, I feel it's important to stress that this should only be done for education purposes; you should be relying on built-in CorsMiddleware and not rolling your own whenever possible (and it should hopefully always be possible).

.netcore session variables always null

I have a .netcore 5.0 web api. And I want to implement session variables for users when logged in.
I believe I followed all the steps on multiple tutorials.
Here is what I've done so far
Startup.c:
My controller class
I have a vuejs app, when I refresh the page I call "OnLoadPage", and when I click a button I call "OnPageGet".
Session variable seems to be set in the scope of the http call, but when I make another http request the session ID fully changes and all my variables are null.
What am I missing please help. Thank you.
I realized it's necessary to setup some cookie parameters to make it work.
In my developper tools I noticed an error on the response of my "PageLoad" request, where it said "samesite error" I just had to add this configuration parameter to my startup and it fixed it.

How do I get Basic Authentication, GlassFish, REST, and a single page application to all work together with my own login form?

I'm using Glassfish 4 as a server with an AngularJS app as a client. Glassfish is exposing a REST API via JAX-RS (Jersey). I'm using Basic Authentication over an HTTPS connection. I have my own login form and am setting the Authorization header in my REST requests via JavaScript. My issue is that if I use normal web.xml based permissions (<auth-constraint> inside <security-constraint>), the responses come back with 401 with a WWW-Authenticate header (if the credentials are bad). This forces the browser to do the Basic Authentication dialog instead of my own and it appears there is no viable cross browser work around available on the browser side to stop it. So I need to somehow suppress the 401/WWW-Authenticate response.
I stopped using the web.xml based permissions, because it seems it is the Servlet level that is doing the 401 stuff. I was able to get Jersey authentication working with a filter and turning on the "RolesAllowedDynamicFeature" feature (in a matter similar to Glassfish #RolesAllowed with custom SecurityContext). That seems to work great and returns 403 for bad credentials (and thus no browser dialog). However, when I call my EJB's, they do not see the custom security context and the user I have set, so I get permission exceptions. If it matters: the EJB's are in a jar, the Jersey stuff is in a war, and both of them and bundled together in an ear. From what I can gather the only way to have the EJB's properly process credentials is to use the web.xml stuff.
I seemed to have painted myself into a corner and do not see how to make this work. Perhaps I can back out and return to using web.xml based permissions and somehow filter the servlet responses to not return 401/WWW-Authenticate? If so I could not find out how to do that. Or is there some way I can set EJB's security context? Or something else entirely? I wouldn't think using AngularJS with GlassFish and a REST API and Basic Authentication would be very unique, how does anyone do this?
Since posting this question I have found info on implementing a Servlet filter and using that to try to change the 401 response to a different status code. However, the filter never gains control if you have <auth-constraint> in your web.xml and the request is not authorized, so that did not help me. I still could not prevent the 401 responses.
But now I think I finally found the answer. I removed the <auth-constraint> tag from web.xml. I changed the Servlet filter to now extract the AUTHENTICATION_HEADER on its own and decode it (via javax.xml.bind.DatatypeConverter). Next I call HttpServletRequest.login (on the request object) with the decoded username and password. I catch the ServletException if the username/password combination is bad and use HttpServletResponse.sendError to send SC_FORBIDDEN. If I have a good login I call doFilter to continue on with processing of the request, and call HttpServletRequest.logout when it returns.
If I do this in combination with RolesAllowedDynamicFeature and annotations on the Jersey routines everything seems to work including calls to EJB's with their own security annotations.
Side note: before settling on HttpServletRequest.login I had tried to use HttpServletRequest.authenticate followed by checking the returned boolean, but when you gain control in that case the response has already been committed to be 401 and you cannot change it. I even tried passing a HttpServletResponseWrapper to authenticate to stop the commit from happening, but authenticate seems to get the response object through some other means, it seems to ignore the one you pass it (I even tried passed null and it didn't even notice).

SAP Gateway runtime odata path permissions

Is there standard way to change runtime permissions for a user to be able to call certain odata resources of a SAP gateway service, other than manually writing code in every service implementation method to check if the request is allowed?
For example, based on some setting in customizing, the odata paths below /foo and /bar for user x should be forbidden, i.e. HTTP GET/POST/DELETE <host>:<port>/foo/test and HTTP GET/POST/DELETE <host>:<port>/bar/test should yield HTTP 403 for user x, but HTTP GET/POST/DELETE <host>:<port>/something should be OK.
Is there a way where this can be controlled at a single place rather than being required to implement a check in every method implementing the odata requests?
The proper place for the authorization check is in the backend method. Any authorization error should populate back to the service and yield a 403 for example.
If you for some reason don't want that, you could write your own HTTP handler and insert it in SICF to be called on all paths.
The standard role setup only allows access or no access to a service, the "pattern" access you are referring to is missing. But I can't really understand why you would want it? It will make your Odata services kind of un-predictable for the consumer, wouldn't it?