Authentication / PrincipalPermission not work

2.4k views Asked by At

I work in WCF and am writing my Authentication Manager which is based on IHttpModule and it works fine. One the of methods in my Authentication class creates a GenericPrincipal object in Context.User.

For example

app.Context.User = new GenericPrincipal(new GenericIdentity("Scott"), new string[] { "read" });

In one of methods in Service I want to assign the user PrincipalPermissionAttribute and I don't how it should work, but it always throws a SecurityException. For example:

    [WebGet(UriTemplate = "/", RequestFormat=WebMessageFormat.Xml, ResponseFormat=WebMessageFormat.Xml)]
    [PrincipalPermission(SecurityAction.Demand, Role="read")]  // it throw SecurityException
    public SampleItem GetCollection()
    {
        bool user = HttpContext.Current.User.IsInRole("read"); // return true
        bool user1 = HttpContext.Current.User.IsInRole("write"); // return false

        return SampleItem.GetSampleItem();
    }

Maybe PrincipalPremissionAttribute doesn't use Context.Current.User? But if not then what?

I tried remove the problem, and made a very simple attribute

[AttributeUsage(AttributeTargets.Method, AllowMultiple=true, Inherited=false)]
public class MyAuthorizationAttribute : Attribute
{
    public MyAuthorizationAttribute(params string[]  roles)
    {
        foreach (string item in roles)
        {
            if(HttpContext.Current.User.IsInRole(item) == false)
            {
                HttpContext.Current.Response.Clear();

                HttpContext.Current.Response.StatusCode = 401;

                HttpContext.Current.Response.AddHeader("WWW-Authenticate", "Basic Realm");
                HttpContext.Current.Response.StatusDescription = "Access Denied";
                HttpContext.Current.Response.Write("401 Access Denied");

                HttpContext.Current.Response.End();
            }
        }
    }
}

But the application can't use this. What I mean is, when I set a breakpoint on the MyAttribute constructor, the compiler doesn't stop on the beakpoint, it doesn't see it.

    [WebGet(UriTemplate = "/", RequestFormat=WebMessageFormat.Xml, ResponseFormat=WebMessageFormat.Xml)]
    [MyAuthorization("read")]
    public SampleItem GetCollection()
    {
        bool user = HttpContext.Current.User.IsInRole("read"); // return true
        bool user1 = HttpContext.Current.User.IsInRole("write"); // return false

        return SampleItem.GetSampleItem();
    }
1

There are 1 answers

1
Marc Gravell On

With WCF you need to associate custom principals via a very specific mechanism, which works fine. Note also that attributes generally do not cause code execution, and only get invoked when done explicitly done via reflection (unless you are using PostSharp). You can't just add an attribute and have it do things automatically. MVC etc gives that impression, but there is code in MVC checking for attributes and executing them manually.