Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WCF Custom Authorization

Basically, I'm creating my first ever WCF web service and I'm looking to implement custom authentication and authorization. The authentication seems to be working well, but I want to be able to store roles and permissions using custom authorization as well.

My authentication is done by overriding UserNamePasswordValidator and making use of the Validate method.

Validate(string UserName, string password)

Now I've tried implementing the authorization by using the IAuthorizationPolicy interface

public class AuthorizationPolicy : IAuthorizationPolicy
{
    private string _id;

    public string Id
    {
        get { return this._id; }
    }

    public ClaimSet Issuer
    {
        get { return ClaimSet.System; }
    }

    public AuthorizationPolicy()
    {
        _id = Guid.NewGuid().ToString();
    }

    public bool Evaluate(EvaluationContext context, ref object state)
    {
        IIdentity client = GetClientIdentity(context);
        context.Properties["Principal"] = new CustomPrincipal(client);

        return true;
    }

    private IIdentity GetClientIdentity(EvaluationContext evaluationContext)
    {
        object obj;
        if (!evaluationContext.Properties.TryGetValue("Identities", out obj))
            throw new Exception("No Identity found");

        IList<IIdentity> identities = obj as IList<IIdentity>;
        if (identities == null || identities.Count <= 0)
            throw new Exception("No Identity found");

        return identities[0];
    }
}

and I've also implemented the CustomPrincipal using the IPrincipal interface.

public class CustomPrincipal : IPrincipal
{
    IIdentity _identity;
    string[] _roles;

    public CustomPrincipal(IIdentity identity)
    {
        _identity = identity;
    }

    public static CustomPrincipal Current
    {
        get
        {
            return Thread.CurrentPrincipal as CustomPrincipal;
        }
    }

    public IIdentity Identity
    {
        get { return _identity; }
    }

    public string[] Roles
    {
        get
        {
            if (_roles == null)
            {
                EnsureRoles();
            }

            return _roles;
        }
    }

    public bool IsInRole(string role)
    {
        EnsureRoles();

        return _roles.Contains(role);
    }

    protected virtual void EnsureRoles()
    {
        UserManager userManager = new UserManager();
        int userPermissions = userManager.UserPermissions(_identity.Name);

        if (userPermissions == 1)
            _roles = new string[1] { "ADMIN" };
        else
            _roles = new string[1] { "USER" };
    }
}

My App.Config has been updated as required, and the Evaluate method in AuthorizationPolicy is called as expected.

However, this is where I'm stuck. How do I go about implementing the roles and permissions from here?

like image 363
Matt Webber Avatar asked Dec 02 '14 08:12

Matt Webber


2 Answers

I would suggest that you opt for a Message Inspector.

The logic would be as follows:

  1. Client will have a message inspector that will set the required headers for each request.
  2. Server side message inspector will intercept the request and then read headers and do the authentication and authorization.
  3. You can have a couple of services like user and role service that can be invoked in the server to validate the credentials in the header and set the identity for that request.
  4. These services will be accessing the store through DAL and will be in inproc mode.
like image 195
Saravanan Avatar answered Nov 05 '22 05:11

Saravanan


You may refer to Authentication and Authorization with ASP.NET Identity 2.0 for WCF Services

Basically you will have 3 levels to consider according to this article:

  1. System.IdentityModel and System.Security.Principal

  2. Asp.net Identity 2.0 if you want to use the out of the box context shared with MVC applications; or you use your custom database.

  3. Policies if you want fine grained controls of security policy

like image 3
ZZZ Avatar answered Nov 05 '22 05:11

ZZZ