0

I would like to know if it's possible to manage users from a WCF service. For example, my app - which is a client of my WCF service - call a function CreateUser(String login, string password, string email), and my service create this user using EF identity and / or ASP Membership.

I've installed nuget packages : OWIN/EF.Identity/ASP membership.

I've already tried to create classes in my WCF service :

ApplicationDBContext :

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
    public ApplicationDbContext()
        : base("Scorpion_V1Users")
    {

    }
}

ApplicationUser :

public class CustomApplicationUser : IdentityUser
{
    public CustomApplicationUser()
    {
        this.Id = Guid.NewGuid().ToString();
    }

    public CustomApplicationUser(string userName): this()
    {
        UserName = userName;
    }

}

My custom UserStore :

public class CustomUserStore : IUserStore<CustomApplicationUser>, IUserPasswordStore<CustomApplicationUser>, IUserSecurityStampStore<CustomApplicationUser>
{
    UserStore<IdentityUser> userStore = new UserStore<IdentityUser>(new CustomApplicationDbContext());
    public CustomUserStore()
    {
    }

    public Task CreateAsync(CustomApplicationUser user)
    {
        var context = userStore.Context as CustomApplicationDbContext;
        context.Users.Add(user);
        context.Configuration.ValidateOnSaveEnabled = false;
        return context.SaveChangesAsync();
    }

    public void Create(CustomApplicationUser user)
    {
        var context = userStore.Context as CustomApplicationDbContext;
        context.Users.Add(user);
        context.Configuration.ValidateOnSaveEnabled = false;
        context.SaveChanges();
    }

    public Task DeleteAsync(CustomApplicationUser user)
    {
        var context = userStore.Context as CustomApplicationDbContext;
        context.Users.Remove(user);
        context.Configuration.ValidateOnSaveEnabled = false;
        return context.SaveChangesAsync();
    }

    public Task<CustomApplicationUser> FindByIdAsync(string userId)
    {
        var context = userStore.Context as CustomApplicationDbContext;
        return context.Users.Where(u => u.Id.ToLower() == userId.ToLower()).FirstOrDefaultAsync();
    }

    public Task<CustomApplicationUser> FindByNameAsync(string userName)
    {
        var context = userStore.Context as CustomApplicationDbContext;
        return context.Users.Where(u => u.UserName.ToLower() == userName.ToLower()).FirstOrDefaultAsync();
    }

    public Task UpdateAsync(CustomApplicationUser user)
    {
        var context = userStore.Context as CustomApplicationDbContext;
        context.Users.Attach(user);
        context.Entry(user).State = EntityState.Modified;
        context.Configuration.ValidateOnSaveEnabled = false;
        return context.SaveChangesAsync();
    }

    public void Dispose()
    {
        userStore.Dispose();
    }

    public Task<string> GetPasswordHashAsync(CustomApplicationUser user)
    {
        var identityUser = ToIdentityUser(user);
        var task = userStore.GetPasswordHashAsync(identityUser);
        SetApplicationUser(user, identityUser);
        return task;
    }

    public Task<bool> HasPasswordAsync(CustomApplicationUser user)
    {
        var identityUser = ToIdentityUser(user);
        var task = userStore.HasPasswordAsync(identityUser);
        SetApplicationUser(user, identityUser);
        return task;
    }

    public Task SetPasswordHashAsync(CustomApplicationUser user, string passwordHash)
    {
        var identityUser = ToIdentityUser(user);
        var task = userStore.SetPasswordHashAsync(identityUser, passwordHash);
        SetApplicationUser(user, identityUser);
        return task;
    }

    public Task<string> GetSecurityStampAsync(CustomApplicationUser user)
    {
        var identityUser = ToIdentityUser(user);
        var task = userStore.GetSecurityStampAsync(identityUser);
        SetApplicationUser(user, identityUser);
        return task;
    }

    public Task SetSecurityStampAsync(CustomApplicationUser user, string stamp)
    {
        var identityUser = ToIdentityUser(user);
        var task = userStore.SetSecurityStampAsync(identityUser, stamp);
        SetApplicationUser(user, identityUser);
        return task;
    }

    private static void SetApplicationUser(CustomApplicationUser user, IdentityUser identityUser)
    {
        user.PasswordHash = identityUser.PasswordHash;
        user.SecurityStamp = identityUser.SecurityStamp;
        user.Id = identityUser.Id;
        user.UserName = identityUser.UserName;
    }

    private IdentityUser ToIdentityUser(CustomApplicationUser user)
    {
        return new IdentityUser
        {
            Id = user.Id,
            PasswordHash = user.PasswordHash,
            SecurityStamp = user.SecurityStamp,
            UserName = user.UserName
        };
    }
}

and my UserManager :

public class CustomUserManager 
{
}

I've created all AspNet tables on my database and added an other EDMX on my WCF project, pointing to them. The newly created connection string is correct (ScorpionV1Users).

Tables

<add name="Scorpion_V1Users" connectionString="metadata=res://*/Database.Users.csdl|res://*/Database.Users.ssdl|res://*/Database.Users.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=TANTO;initial catalog=Scorpion_V1;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework&quot;" providerName="System.Data.EntityClient" />

When I try

private CustomUserStore _userStore = new CustomUserStore();
...
var user = new CustomApplicationUser { UserName = login, Email = mail };
_userStore.Create(user);

in UserStore,

public void Create(CustomApplicationUser user)
    {
        var context = userStore.Context as CustomApplicationDbContext;
        context.Users.Add(user);
        context.Configuration.ValidateOnSaveEnabled = false;
        context.SaveChanges();
    }

the line

context.Users.Add(user);

throw an error : 'The entity type CustomApplicationUser is not part of the model for the current context'.

I've seen other issues like that, here, or here, but it does not resolve mine aswell.

I think my model to create AspNetUsers is not complete. What else do I need (classes, nuget package or smt else) to implement it ?

Thanks in advance.

Community
  • 1
  • 1
Thib
  • 55
  • 12

1 Answers1

0

Irrespective of WCF you can use

[PrincipalPermission(SecurityAction.Demand, Role = "usernane")]
bernhof
  • 6,219
  • 2
  • 45
  • 71
Krtti
  • 62
  • 10