2

I refer specifically to the accepted answer for Impersonating user with Entity Framework, which sports the following code:

using (((WindowsIdentity)HttpContext.Current.User.Identity).Impersonate())
using (var dbContext = new MyEntityFrameworkContainer())
{
    ...
}

I would rather instantiate dbContext at only one place in my repositories, which implement IDisposable, and then dispose of the context when the entity is disposed of. I'm not sure how the two using scopes above affect each other though, so how can I achieve what this code does in terms of impersonation while avoiding the using blocks?

ADDED: As answers below have suggested, I can simply use local variables and 'manually' ensure the resources are disposed, but my concern here is whether the instantiation in the inner using is in any way affect by the outer using. If this is only a matter of lifetime, and the outer using doesn't establish any context or anything that affects the inner, then the below answers have answered my question.

Community
  • 1
  • 1
ProfK
  • 49,207
  • 121
  • 399
  • 775
  • Side note: prolonging lifetime of objects created while under impersonated user identity (DB connections, files, processes) could be serious security problem. Consider making it hard to continue using such object after finishing impersonation. Making something like Repository.ForImpersonatedUser(identity) may be an option. – Alexei Levenkov Apr 17 '12 at 22:25
  • @AlexeiLevenkov, I don't understand what you are suggesting I do with `Repository.ForImpersonatedUser(identity)` – ProfK Apr 18 '12 at 11:56
  • Your repository likely contains objects that where created during impersonation (i.e. connection to DB made under particular user's account). If this object is shared with other code that may or may not run under the same user's identity you have a problem. So you can have repository for objects created for particular user and destroy the repository as soon as you are done with impersonation. Depending on sensitivity of the data you may need to write extra code to force objects to not provide any information after impersonation is over. – Alexei Levenkov Apr 18 '12 at 16:06
  • @AlexeiLevenkov, so `ForImpersonatedUser` is a factor method that returns a repo that is impersonating the passed identity? – ProfK Apr 18 '12 at 19:52
  • Yes. Pick whatever way to implement it if you happen to have the issue - I was just trying to come up with short self-descriptive name... – Alexei Levenkov Apr 18 '12 at 20:24

2 Answers2

2

You can declare them as 2 private fields and instantiate them in the constructor.

Then implement Dispose() and Dispose them in reverse order.

And then of course the calling code (Business layer) should apply the using(){} pattern to Repository instances.

Additional:

The nested usings should not be important. Impersonate() is a state-change that affects the current thread. The using-implied Dispose() would call Undo().

Community
  • 1
  • 1
H H
  • 263,252
  • 30
  • 330
  • 514
  • the outer `using` doesn't return any value for me to store. I imagine the nested using was doing some voodoo here I didn't want to break. – ProfK Apr 18 '12 at 11:58
  • You can simply look at it as `using(myTemp = ...)`. – H H Apr 18 '12 at 12:12
1
var id = ((WindowsIdentity)HttpContext.Current.User.Identity).Impersonate();
//store id
//do whatever you want, for example store this variable in a field
id.Dispose(); //remove impersonation
usr
  • 168,620
  • 35
  • 240
  • 369
  • The `var` implies local vars. This would only remove exception-safety, it adds nothing. – H H Apr 17 '12 at 22:09
  • He can store the contents of this variable anywhere, including in a field. I added this possibility as a comment. – usr Apr 17 '12 at 22:11
  • @usr, What do I do with the stored `id`? I assumed that with the code in the answer I refer to, the `dbContext` created inside the outer `using` somehow uses that value implicitly. – ProfK Apr 18 '12 at 12:00
  • Probably I misunderstood the question somehow and solved the wrong problem. Not sure. – usr Apr 18 '12 at 12:22