简体   繁体   中英

WCF Forms Authentication authorization using ASP.NET roles = Access Denied?

I have a basic WPF application where the client writes to a database. I'm using IIS on a server 2012 machine to host the web service. I'm trying to implement Forms authentication, and I have all that working (passing a username and password in the xaml.cs from the client which authenticates my ASP.NET user which works. I then want to implement ASP.NET roles authorization for different commands (Submit Request, Remove Request, etc). The method we're supposed to use is "[PrincipalPermission(SecurityAction.Demand, Role = "Allowed")]"

In theory this should just use the credentials passed in the client (which I've confirmed works) when I try to hit the buttons and it should check if the user I passed is in the role, and if so it allows and if not it denies. However, whether or not the user is in the role it still says "Access is Denied".

Any thoughts?

using System;
using System.Collections.Generic;
using System.Data.Entity.Validation;
using System.Diagnostics;
using System.Linq;
using System.ServiceModel;
using System.Security.Permissions;
using RequestRepository;
using System.Threading;
using System.Web;

namespace RequestServiceLibrary
{
  [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
  public class RequestService : IRequestService
  {
    private List<Request> requests = new List<Request>();
    private RequestLibraryEntities context = new RequestLibraryEntities();

    [PrincipalPermission(SecurityAction.Demand, Role = "Allowed")]
    public string SubmitRequest(Request req)
    {
        Thread.CurrentPrincipal = HttpContext.Current.User;
        if (context.Requests.Count() == 0)
            populateRequests();
        req.Id = Guid.NewGuid().ToString();
        req.TimeSubmitted = DateTime.Now;
        requests.Add(req);
        addRequest(req);
        return req.Id;
    }

    [PrincipalPermission(SecurityAction.Demand, Role = "Allowed")]
    public bool UpdateRequest(Request req)
    {
        Thread.CurrentPrincipal = HttpContext.Current.User;
        bool returnval = false;
        try
        {
            var getobject = requests.Find(x => x.Id.Equals(req.Id));
            if (getobject != null)  //checks to make sure the object isn't empty
            {
                getobject.Username = req.Username;
                getobject.Password = req.Password;
                getobject.RequestedResource = req.RequestedResource;
                getobject.TimeSubmitted = req.TimeSubmitted;
            }
            //Find the request object in the database
            var Id = Guid.Parse(req.Id);
            var rl = context.Requests.Find(Id);
            //Update that object with the values from req            
            rl.Username = req.Username;
            rl.Password = req.Password;
            rl.RequestedResource = req.RequestedResource;
            rl.TimeTransmitted = req.TimeSubmitted;
            context.SaveChanges();
            returnval = true;
            return returnval;
        }
        catch (Exception) { return returnval; }
    }
    public List<Request> GetRequests()
    {
        populateRequests();
        return requests;
    }

    [PrincipalPermission(SecurityAction.Demand, Role = "Disallowed")]
    public bool RemoveRequest(string id)
    {
        bool rval = false;
        try
        {
            Request req = requests.Find(x => x.Id.Equals(id));
            requests.Remove(req);
            rval = delRequest(req);
            return rval;
        }
        catch (Exception)
        {
            return false;
        }
    }


    private void populateRequests()
    {
        requests = new List<Request>();
        var rl = context.Requests.ToList();
        foreach (var r in rl)
        {
            requests.Add(new Request()
            {
                Id = r.Id.ToString(),
                Password = r.Password,
                RequestedResource = r.RequestedResource,
                TimeSubmitted = r.TimeTransmitted,
                Username = r.Username
            });
        }
    }

    private void addRequest(Request req)
    {
        try
        {
            var r = context.Requests.Create();
            r.Id = Guid.Parse(req.Id);
            r.Username = req.Username;
            r.Password = req.Password;
            r.RequestedResource = req.RequestedResource;
            r.TimeTransmitted = req.TimeSubmitted;
            context.Requests.Add(r);
            context.SaveChanges();
        }
        catch (DbEntityValidationException dbEx)
        {
            foreach (var validationErrors in dbEx.EntityValidationErrors)
            {
                foreach (var validationError in validationErrors.ValidationErrors)
                {
                    Console.WriteLine("Property: {0} Error: {1}", validationError.PropertyName, validationError.ErrorMessage);
                }
            }
        }
    }


    private bool delRequest(Request req)
    {
        Guid Id = Guid.Parse(req.Id);
        var r = context.Requests.Create();
        r.Id = Id;
        var rl = context.Requests.Find(Id);
        try
        {
            context.Requests.Remove(rl);
            context.SaveChanges();
            return true;
        }
        catch (Exception) { return false; }
    }

  }
}

In order to be able to use PrincipalPermissionAttribute in this way, you need to first set Thread.CurrentPrincipal to a Principal with the appropriate roles ("Allowed" in this case).

For example you could use ClientRoleProvider to do this, or simply create the Principal manually (possibly using roles you retrieve from the web service).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM