ValidateAntiForgeryToken breaks read on .NET Core with IdentityServer4 - asp.net-core-mvc

I am doing a basic read and write functionality to a IdentityServer4 application using .NET Core 2.0 and have come across an issue. When trying to load clients the ValidateAntiForgeryToken attribute seem to break my update.
I know that EF core does not support lazy loading so we are using an Unit Of Work pattern. I would create separate repositories for Client, ClientScopes, Secrets, etc. and grab the data for each. I will pass in a Func<> to allow filtering when grabbing ClientScopes etc. So a method call would look like this
ClientScopeResitory.GetAll(a => a.Client.Id == id)
which would then access the dbset like this
public IEnumerable GetAll(Func<T, object> predicate == null)
{
return predicate != null ? dbset.Where(predicate) : dbset
}
My issue is when loading the client in my read operation this works just fine. However when using the same code in my update where the ValidateAntiForgeryToken is present it breaks. What happens is in the creation of the repository during the read, the Clients are loaded in with the dbset. However, in the update, the clients are not. When the ValidateAntiForgery attribute is removed. The clients are loaded again and the update works fine. Anyone have any ideas what is going on. I can supply full code upon request. Thanks in advance.
Also, I apologies for any bad grammar or spelling, I wrote this in a hurry

Related

Session object not available in WebAPI

I've got a webAPI that uses Entity Framework. I'm trying to cache some data in the session variable following along in this article:
https://msdn.microsoft.com/en-us/library/system.web.httpcontext.session(v=vs.110).aspx
I can't seem to do it though. The Session object isn't available.
In my controller, I try this:
Session["mappings"] = mappings;
...but it doesn't recognize what Session is.
I also try this:
HttpContext.Current.Session["mappings"] = mappings;
...and this:
Page.Session["mappings"] = mappings;
...but it doesn't know what HttpContext or Page are.
I'm including System.Web in my project references. I'm also including this in my web.config:
...just like this article says:
https://msdn.microsoft.com/en-us/library/ms178581(v=vs.110).aspx
...but to no avail.
My work colleague suggests it's because our webAPI is RESTful which means it's stateless, so no session object. However, we know there are ways around this. What I need is simply some way of persisting data in some kind of cache that will survive across several requests.
I also need something that will be available inside EF entities (not just the webAPI controller) is that's possible.
Does anyone know how to solve this problem? Thanks.
As your colleagues correctly suggested, an API is stateless, each request is separate and needs to have all the data required to complete the request.
You can add a caching layer however, but that is not going to be done via the Session object. Session makes no sense in an API.
Have a look here for some ideas: Caching Data in Web API

Umbraco: Problems getting member data with custom membership provider

In short, I have created a custom membership provider and a custom member. This is using the "old" .NET membership provider system. Right now I can log in successfully, and the custom member is accepted by the system as well.
Note: Only methods implemented so far in the membership provider is "ValidateUser(name, pass)" and "GetUSer(username, isonline)"
The problem is, I cant get any info from the custom member. Nothing. Everything I have tried fails. I dont think it will even matter to list what I have tried, and Googling doesnt return anything that works. Its funny how I feel like the only person in the world who has a custom member, but obviously I cant be :/
I am using Umbraco 7.5.2 if it helps.
EDIT
Ok here is one of the things I have tried:
Membership.GetUser()
Apparently that doesnt work in MVC4+ and I am using MVC 5. I also tried casting it to my custom member type of course, but it's always null.
Also for current Umbraco guides they all apply to the built in member service in Umbraco 7 which is totally different than the old way of doing it.
I was under the impression that once a user was logged in, the information stored in the user/member object was readily available in the front end.
EDIT 2
I have the following solution but it is far from perfect. When getting the user that is currently logging in, before I return the custom membership user, I send the entire object to the session, and get information like this:
#if (Members.IsLoggedIn())
{
Site.Extensions.TripleAMembershipUser tmpUser = new Site.Extensions.TripleAMembershipUser();
if (Session["currentUser"] != null)
{
tmpUser = (Site.Extensions.TripleAMembershipUser)Session["currentUser"];
<div><h1>#tmpUser.someCustomString</h1></div>
}
}

"Default principal object cannot be set twice" error implementing WEB API with CSLA backend

Can anyone save some of my hair? :)
I'm trying to create an asp.net WEB API interface for an older CSLA (1.x/2.x era) project. I am testing by hard coding the login on every request in various ways (once in the startup code, as an authorization request filter, inside the individual route request etc etc). All the ways I tried work exactly once perfectly and then I get the infamous:
'Default principal object cannot be set twice.'
exception in BusinessPrincipal.vb (yeah I know it's very old, but it's released software, I can't upgrade CSLA)
I know that there is an issue where you need to set HttpContext.Current.User = Thread.CurrentPrincipal; due to some internal workings of the web API and I do that already, that has not resolved the issue.
I'd like to know if anyone has implemented a web api front end and how they handled this issue or any pointers as to what could be the solution.
Worst case scenario if I could at least just login once and keep that same principal without losing it I could implement a second layer of security, that woudld be acceptable, barring anything else is there some way to just login once and not lose that principal?
That BusinessPrincipal class would be in your code base, not in CSLA itself. The Csla.Security namespace does include a BusinessPrincipalBase that is probably the base class for your BusinessPrincipal.
Classes in that namespace are here in GitHub
It is true that you can only call AppDomain.SetPrincipalPolicy one time, but you should be able to set the Thread.CurrentPrincipal and HttpContext.Current.User multiple times.

Returning child elements in ASP.NET WebAPI OData

I'm using the latest ASP.Net WebAPI Nightly builds (dated 2013-01-16).
I have a simple EF database first model at the moment that has two entities - Patients and Visits. Each patient can have many visits.
I'd like to be able to query for my list of patients and have the visits entities for each patient returned inline. I know that WebAPI's OData implementation doesn't yet support $expand. I'm hoping that just means that optional client-controlled expansion is not supported and that I can force expansion server-side.
At the moment I'm not getting any of the visits inline.
For example, my PatientController's() Get() method looks like
[Queryable(AllowedQueryOptions=AllowedQueryOptions.Supported)]
public override IQueryable<Patient> Get()
{
var query = this.entities.Patients.Include("Visits");
return query;
}
I've verified that the query executing against my database does indeed include the visit information.
To use a publicly available OData service as an example, if you use the service at http://services.odata.org/OData/OData.svc/, you can get a list of Suppliers. This is http://http://services.odata.org/OData/OData.svc/Suppliers.
You can also ask for a list of suppliers that includes the list of products using http://http://services.odata.org/OData/OData.svc/Suppliers?$expand=Products
Stepping through the ASP.NET code (via the symbols server) I've got to the System.Web.Http.OData.Formatter.Serialization.ODataEntityTypeSerializer and can see that it's CreatePropertyBag method, which builds up the list of properties to be serialized, just doesn't include the navigation properties, and they don't seem to be enumerated anywhere else apart from being written out as NavigationLinks.
I'm quite new to the ASP.NET world in general and have spent a week or so getting my head around the way things work (particularly with the changes made to OData at the end of 2012 and further changes made so far in 2013).
I suspect that if the ODataEntityTypeSerializer was to be modified (I'm happy to try) to embed this extra information in the appropriate spot (within each navigation link as an nested inline feed as best I can tell) then I'd be set.
Questions:
Have I overlooked something obvious and there's a flag I can set to turn on this behaviour? I can see why, if such a flag exists, it would be off by default (EF lazy loading and this flag wouldn't get on well)
If #1 is no, is there some other ODataEntityTypeSerializer that I could use? If so, how do I switch to it?
If #2 is no, any pointers for where I should start writing my own? Is there a place I can substitute in my own serializer or do I have to maintain my own fork of ASP.NET's Extensions project (as opposed to the Runtime project)
Thanks very much!
$expand is very high on our list of things to support for OData. But as far as I know, we don't have any flag to turn it on server-side. The formatter doesn't currently allow you to substitute your own serializers either. So I'm afraid your only option in the meantime is to create a fork and add support for $expand. If you manage to get it working, please consider sending a pull request our way:
http://aspnetwebstack.codeplex.com/SourceControl/network
You can try it already in webapi nightly builds.
Here is how to install it with nuget:
http://aspnetwebstack.codeplex.com/wikipage?title=Use%20Nightly%20Builds

ASP.NET MVC 3, RavenDB, & Autofac Issue Plus 2 Other Autofac Questions

NOTE: There are 3 questions in here and I did not make separate questions since they are all somewhat related to the same code.
I have the following code that registers the connection to my RavenDB in the Application_Start once per the application's life cycle:
var store = new DocumentStore { Url = "http://localhost:8080" };
store.Initialize();
builder.RegisterInstance(store).SingleInstance();
Now this works fine and this is something that should be created only once per the application's life cycle. Now I wanted to add in the DocumentSession to Autofac so I tried to add in this in the Application_Start:
var session = store.OpenSession();
builder.RegisterInstance(session).SingleInstance();
In my UserRepository I have the following constructor:
public UserRepository(DocumentStore store, DocumentSession session)
When I try to run this, I get the follow runtime error:
Cannot resolve parameter 'Raven.Client.Document.DocumentSession Session' of constructor 'Void .ctor(Raven.Client.Document.DocumentStore, Raven.Client.Document.DocumentSession)'
That error to me sounds like Autofac does not think it has a DocumentSession however that is what store.OpenSession() returns so it should. Anyone know what would be causing this error? Am I not setting the session variable correctly (it is the same as the store variable which works fine)?
Another thing which may or may not be related to the above issue is how do I add an instance of an object to Autofac per request instead of per the applications life cycle? While the RavenDB DocumentStore object should only be created once be the life application cycle, the DocumentSession should be created once per the request (maybe creating it per application level is causing the error above).
One last question I will throw there about Autofac (mildly related to the code above) is about releasing the objects. If you take a look at this tutorial:
http://codeofrob.com/archive/2010/09/29/ravendb-image-gallery-project-iii-the-application-lifecycle.aspx
The last piece of code:
ObjectFactory.ReleaseAndDisposeAllHttpScopedObjects();
and the point of this code is to prevent leaking the sessions. Now is this something I also need to worry about for Autofac and if so, how would I do this in Autofac?
I'm guessing you want something like:
builder.Register(c => c.Resolve<DocumentStore>().OpenSession()).InstancePerLifetimeScope();
"The default ASP.NET and WCF integrations are set up so that InstancePerLifetimeScope() will attach a component to the current web request or service method call." - Autofac: InstanceScope
Basically, in a web app, InstancePerLifetimeScope handles the one per HTTP context aspect, and also disposes any types that implement IDisposable.
There was also the issue that OpenSession returns a IDocumentSession instead of a DocumentSession. Changing my class to look for a IDocumentSession along with doing what Jim suggested worked, thanks.

Resources