5

A user triggers a event, thus the thread is in the context of said user. I iterate over all connected users and want to send them this event, but I want to use classic Authorization to determine if they should receive the event. Problem is the thread principal etc is in the context of the user that triggered the event.

I'm looking into impersonate the thread and then do the authorization. I found this article on it

http://msdn.microsoft.com/en-us/library/ff647248.aspx#ImpersonationDelegation5

using System.Security.Principal;
…
WindowsIdentity wi = new WindowsIdentity(userName@fullyqualifieddomainName);
WindowsImpersonationContext ctx = null;

try
{
  ctx = wi.Impersonate();
  // Thread is now impersonating you can call the backend operations here...

catch
{
  // Prevent exceptions propagating.
}
finally
{
  // Ensure impersonation is reverted
  ctx.Undo();
}

After ctx = wi.Impersonate(); the thread is still in the context of the calling user, what am I doing wrong?

update I want to run this code as the other user

provider = AuthorizationFactory.GetAuthorizationProvider();
provider.Authorize(Thread.CurrentPrincipal, Rule)

A little blogpost i did that covers the steps needed http://andersmalmgren.com/2014/06/12/client-server-event-aggregation-with-role-authorization/

Anders
  • 17,306
  • 10
  • 76
  • 144
  • does an exception occur? the code does not catch any, so I am curious! are you within a wcf-context (because the documentation you mentioned supposes so) - if so, would you please add an appropriate tag? –  Jun 12 '14 at 09:00
  • I'm in a HTTP context (WebApi), no errors but Thread.CurrentPrincipal.Identity.Name returns the orignal caller not the improsanated one – Anders Jun 12 '14 at 09:03
  • Have you setup Delegation in your AD for the application? Have you setup your SPN on your host? Have you connected to the server via the FQDN? Have you sacrificed a virgin (intern developer are ok) to the three headed demon dog of the underworld? – Aron Jun 12 '14 at 09:05
  • Actually...come to think about it. Do you know the difference between Delegation and Impersonation? – Aron Jun 12 '14 at 09:08
  • @Anders is your `WindowsImpersonationContext` null? What does `System.Security.Principal.WindowsIdentity.GetCurrent().Name` say before and after your tried impersonation? –  Jun 12 '14 at 09:10
  • Yes I think I have configured Delegation correctly (I think because its not trivial). Is there no other way to change principal without using delegation – Anders Jun 12 '14 at 09:15
  • The WindowsIdentity i get is authenticated so the delegation part should work? – Anders Jun 12 '14 at 09:17
  • What context are you running in? ASP.Net/Owin/WinForm/WPF/WCF? What is "Thread is now impersonating you can call the backend operations here" does it include any resources that are "off-box"? – Aron Jun 12 '14 at 09:18
  • @Anders No. It is authenticated within a very specific context. – Aron Jun 12 '14 at 09:18
  • @Anders do you simply want to set the `Principal` of your `Thread`, or do you need authentication for special actions (like writing files to local disc, etc)? Impersonation/Delegation is usually used for "off-box" (like @Aron said) actions, but does not necessarily change the `Principal` of the current thread. –  Jun 12 '14 at 09:19
  • @Anders also. It is VERY important to note if "special actions" are local or remote. It makes a HUGE difference. – Aron Jun 12 '14 at 09:20
  • @AndreasNiedermair correction. Delegation is for off-box or (multi-hop) and requires Kerberos. Impersonation is of single hop auth/auth and can "simply" use NTLM which is much much much much easier to setup. – Aron Jun 12 '14 at 09:22
  • Please take a look at this to make sure you have Kerberos Delegation setup http://www.iis.net/downloads/community/2009/06/delegconfig-v2-beta-(delegation-kerberos-configuration-tool) – Aron Jun 12 '14 at 09:23
  • @Aron dah, you just destroyed my no-brainer :) I understood your "off-box" more like other pc and/or other proc/entity/domain/... which stands for multi and/or single-hoop in one word, very problematic indeed! –  Jun 12 '14 at 09:23
  • @AndreasNiedermair typical use of impersonation. User on PC Client accesses IIS/ASP.Net server on Servce PC. Typical use of delegation. User on PC Client accesses IIS/ASP.Net server who then uses the client's credentials which were transmitted by the client to the web server to access the third machine (typically a SQL server using SSPI). I have literally spent a man month setting up the latter. – Aron Jun 12 '14 at 09:26
  • I want to use our standard authorization mechanism (Ent.lib). So I do not need to write files, connect to DB or anything, it just need to work against ent lib authorization attribute – Anders Jun 12 '14 at 09:26
  • @Anders you have still not told me what your N-Tier architecture looks like. – Aron Jun 12 '14 at 09:27
  • @Aron Thanks for clarification, I know the difference anyway (and have struggled with both scenarios ...) ;) I just used "box" of "off-box" for machine (delegation) and proc (impersonation) (yah, i know ... not really proc ... but you get the idea) equally... –  Jun 12 '14 at 09:28
  • @Aron I've already asked that, and received an answer: "I'm in a HTTP context (WebApi)". I'd go for ASP.Net. (correct tag is still missing) –  Jun 12 '14 at 09:30
  • Please see update of question – Anders Jun 12 '14 at 09:31
  • In that case...any reason you don't just use windows auth impersonation on, in web.config? – Aron Jun 12 '14 at 13:02
  • I am using Windows auth. But I dont want to impersonate the entire web site. This is just for domain events that are triggered by one principal and needs to be tested for secutiry against another – Anders Jun 12 '14 at 13:37

1 Answers1

0

provider.Authorize(principal, context) has System.Security.Principal.IPrincipal as its first paramter (see msdn). Why not create a System.Security.Principal.WindowsPrincipal-instance (which takes a System.Security.Principal.WindowsIdentity-instance, which you already have, as the ctor-parameter) and use it as the parameter?

Otherwise: Did you know that CurrentPrincipal of a thread has a setter? Please see other so-question/answer

Community
  • 1
  • 1
  • We are executing code in layers below that uses current principal, but I can change the thread's principal offcourse since its not async. Will test and get back to you. (After lunch ;)) – Anders Jun 12 '14 at 09:38
  • I just updated my answer with information of how to change `CurrentPrincipal` of a thread ... –  Jun 12 '14 at 09:39
  • It works, a side note, Impersonate() should not be called. IsInRole will fail after that. Otherwise Both standard IsInRole and Ent.lib Rule authorization works! – Anders Jun 12 '14 at 11:36
  • Created a little blog post about this http://andersmalmgren.com/2014/06/12/client-server-event-aggregation-with-role-authorization/ – Anders Jun 12 '14 at 12:33
  • @Anders You could also turn `WindowsAuthentication` on and use the `Microsoft.AspNet.SignalR.AuthorizeAttribute` (which does all the validation against roles and stuff) - unfortunately this would impersonate eg access to file-system too ... (see: http://www.asp.net/signalr/overview/signalr-20/security/hub-authorization) –  Jun 12 '14 at 14:02
  • that is only used to Authorize MVC or WebApi controllers or SignalR hubs. And we use tha too, this is something else :D – Anders Jun 12 '14 at 14:04
  • @Andres nope, there's one in the signalR-namespace too - I've properly edited my comment :) –  Jun 12 '14 at 14:05
  • That attribute only controls access to hub methods. I want to control access to which events are forwarded to clients – Anders Jun 12 '14 at 14:06
  • @Anders Well, that's a proper reason ;) As long as you store the `WindowsPrincipal` on the server and check the outbound calls against your desired instance, you are all set - but if you'd do inbound calls, you could enable `WindowsAuthentication` for your signalR-path and use the `Microsoft.AspNet.SignalR.AuthorizeAttribute` to ensure proper authorization. –  Jun 12 '14 at 14:09
  • @Anders One last thing - I'd would be waaaay better for future questions if you'd include such details in your question first off. This would give interested guys much more possibilities and a deeper understanding of your problem. –  Jun 12 '14 at 14:11
  • I didnt want to go off track with SignalR since this is more a question about .NET authorization. If you are interested you can read more about My Library here http://andersmalmgren.com/2014/05/27/client-server-event-aggregation-with-signalr/ – Anders Jun 12 '14 at 14:12
  • 1
    @Anders The problem is that security is a cross-cutting concern. This means that how it is done is affected by almost every decision you make on your architecture. – Aron Jun 13 '14 at 02:18