My question involves both a technical and a modeling issue.
I have a MCV 5 system where there will be a web front-end and also a mobile app(Android).
At some point the web user will be able to see a queue of mobile signed-on users.
Mobile accounts wont access web front-end neither web accounts the mobile app.
I have chosen Azure to provide all my system needs.
Modeling wise, should I create separate login systems(one more backend system for mobile login)?
If not, is the Asp.net Identity system capable of using two different logins, as I tought roughly something like this:
namespace Application.Models {
// You can add profile data for the user by adding more properties to your ApplicationUser class, please visit http://go.microsoft.com/fwlink/?LinkID=317594 to learn more.
public class ApplicationUser : IdentityUser
{
public virtual ICollection<ApplicationMobileClient> Clients { get; set; }
}
public class ApplicationMobileClient : IdentityUser
{
}
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext()
: base("DefaultConnection")
{
}
}
}
The web user model would have a collection of mobile clients model. Just like an photo/comments system. But I dont know(well I asume not) if the Identity can do something like this, handle two logins on same application. I could Maybe im just larning too much technologies/frameworks/metodologies/patters at the same time and Im just dont know what to do lol.
I can't see why you should need two different ApplicationUser. Because it's the same user regardless if he is on your website or signed in through your Android app. If you want to keep track of the users mobile sign ins then you can add a property to the ApplicationUser.
public class ApplicationUser : IdentityUser
{
public virtual ICollection<MobileSignIn> MobileSignIns { get; set; }
}
public class MobileSignIn
{
}
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext()
: base("DefaultConnection")
{ }
}
Related
Is it possible to put users created from ASP.NET Identity Roles into an organisational unit as you can in Active Directory? I want to be able to allow users to be put into departments where managers of that department can access other users' data only within their own departments. For example, an HR manager should be able to access all of the HR employees' data but not operations or IT employees. I then want to allow managers higher up access to everyone's data. Does ASP.NET's roles and identity allow for this?
Should I use the claims to put users into departments and use policy to add people to management?
It should act as a tree structure, similar to what you can get in Active Directory. However, I can not find an option in asp.net identity that allows the option of organisations.
Yes, it is possible. Asp.NET identity allow you to use classes inherited from IdentityUser or IdentityRole
For example you can add support for User Hierarchy by creating a class that inherits from IdentityUser
public class AppUser : IdentityUser
{
public string ManagerId { get; set; }
public AppUser Manager { get; set; }
public ICollection<AppUser> DirectSubordinates;
}
Then change your ApplicationDbContext to inherit from IdentityDbContext<AppUser> instead of from default IdentityDbContext
public class ApplicationDbContext : IdentityDbContext<AppUser>
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
}
After changing the hierarchy use dotnet-ef tool to add migration then update your database.
You can also uses a class inherited from IdentityRole as follows:
public class ApplicationDbContext : IdentityDbContext<AppUser, AppRole, string>
where AppRole is a class inheriting from IdentityRole
I have a project where I have to make an ASP.NET Core MVC Web Application in which I should include user sign up, login, and an SQL database with basic CRUD operations and corresponding views. For login and signup I decided to use Asp.Net Core Identity following this tutorial: https://youtu.be/CzRM-hOe35o. Everything works and looks fine for signup and login but I can't figure out how to use my database with the database generated by Identity.
My idea for a project database was to have a table for a User and Article (there are more tables but I'm going to keep it simple to explain my problem) with one to many relation. Now that I have a generated database for all things about Users(from Identity tutorial) how can I include this Article table in the databse and make a one to many relation between AspNetUsers and Article?
Or can I use two databases in my project, one with Users and the other one with other project tables? But then how to make relations between tables from different databases, and is it even possible?
First of all, you should know that you can use two databases but never on this case.
To do what you want, follow those steps:
Step 1 - Create a class called "User" in project folder called "Data". Class will be like this:
public class User : IdentityUser
{
}
Step 2- Create another class called "Article" in the same folder called "Data".
public class Article
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
public virtual User User { get; set; }
}
Step 3 - Go to "User" class that you created in the step one and edit it to look like this
public class User : IdentityUser
{
public virtual ICollection<Article> Articles { get; set; }
}
Step 4 - In the same folder where you added those two classes you have another class called "ApplicationDbContext". Open it and register User and Article classes.
public class ApplicationDbContext : IdentityDbContext
{
public DbSet<User> Users { get; set; }
public DbSet<Article> Articles { get; set; }
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
}
Step 5 - delete in your local database the existing db generated from your project before.
After that "Add-migration" and "Update-database"
For more information about how Entity Framework Core works see the link : https://www.learnentityframeworkcore.com/conventions/one-to-many-relationship#:~:text=The%20easiest%20way%20to%20configure,public%20class%20Author
I'm trying to create a reusable base for future web applications made with asp net core.
I created a library that contains a BaseDbContext that inherit from IdentityDbContext:
public class BaseDbContext : IdentityDbContext<ApplicationUser>
{
public BaseDbContext(DbContextOptions options) : base(options)
{
}
}
Inside this library there are some services for login and creation of Users.
Everytime that I will be creating a new WebApplication I will reference the library and I will create a new DbContext like this:
public class ProjectDbContext : BaseDbContext
{
//some generics DBSET
public ProjectDbContext (DbContextOptions<ProjectDbContext> options) : base(options)
{
}
}
And in the startup:
services.AddDbContext<ProjectDbContext>(options =>
{
options.UseSqlServer(connection);
});
Since the service for the login and creation of users require a reference of BaseDbContext, I created a IDbContextFactory inside the base project that will be implemented by the main project like this:
public class ProjectContextFactory : IDbContextFactory
{
private readonly ProjectDbContext _projectDbContext;
public ProjectDbContextFactory(ProjectDbContext remDbContext)
{
_remDbContext = remDbContext;
}
public BaseDbContext GetBaseDbContext()
{
return _projectDbContext;
}
}
This factory will be used inside the base project to get a reference to the BaseDbContext.
Is this a good thing to do? Can this create some kind of problems?
In general, no, this is not a good thing to do.
that will contains the entities that will be used for all web applications
If there's entities that are common to all projects, then those should be factored out completely. In other words, you'd have one project (your base project) with a context like UserContext, which will have your User and Credential entities, and then every other project would have its own separate context that deals with just what it needs. If the other application(s) need to access users, they'd either do so via an instance of UserContext or, better, through a service, such as an API.
That said, it sounds like you're rolling your own auth, which you should emphatically not do. Use Identity. And, if you need to share that between applications, you need a centralized auth provider, such as Identity Server.
In my first project going real DDD, I'm stuck with some doubts concerning which course to take in this scenario...
I have a distributed architecture, in which users of several applications will have only one account that will make them able to authenticate. This account can be created on our own system, or the user can share with us his login with facebook, google and other third-party account provider.
So, there's a project for only this purpose, control user accounts.
This scenario made me came with this approach within my model (simplified):
public class User
{
public User(string name)
{
Id = Guid.NewGuid();
Name = name;
}
public Guid Id { get; protected set; }
public string Name { get; protected set; }
}
public abstract class Account
{
protected Account(User user)
{
Id = Guid.NewGuid();
User = user;
}
public Guid Id { get; protected set; }
public User User { get; protected set; }
}
public class MySystemAccount : Account
{
public MySystemAccount(string email, string password, User user)
: base(user)
{
Email = email;
Password = password;
}
public string Email { get; protected set; }
public string Password { get; protected set; }
}
public class FacebookAccount : Account
{
public FacebookAccount(string facebookId, User user)
: base(user)
{
FacebookId = facebookId;
}
public string FacebookId { get; protected set; }
}
The thing is that the other applications will access this project via REST services.
So, I thought about a single /Authenticate service that will provide a json with dynamic form. It could de a json with a email/password, or a json with the facebookId.
But then, how can I connect the layers?
I thought about making an application service, but I got stuck on who and how should decide what is going on, what should my rest service communicate to the application and how the application will know to do the thing, whatever kind of authentication it is, an user from my own domain or a user from facebook and so on..
Any thoughts on this?
Thanks!
This seems to be a multi-part question - one part about the object model and polymorphism and another about architecture.
Regarding the object model, the use of inheritance isn't ideal in this scenario. Each sub-type of Account won't really have much specific behavior or any behavior at all. The only specialization is the presence of different data fields. Additionally, use of inheritance will complicate persistence.
Architecturally, what I think you're trying to achieve is federated identity. This basically decouples the notion of a user (an identity) from the authentication process. In turn, this allows all remaining application code to bypass authentication concerns and depend only on the user's identity. Take a look at OpenID as well as the DotNetOpenAuth library which provides an OpenID implementation in C#.
I'm new to Stackoverflow, so not sure how to just put this as a "suggestion", but I would rethink your model a little bit. I think of a "User" as someone who strictly is a person utilizing your application through your own website. This "User" would go through the authentication as you suggested, either via an account from your own system, or via an Open ID or OAuth ID provider like Facebook and Google.
If an application however, wants to access your "application" via REST calls, then I'd put them through a different authentication mechanism. In a sense to me, you are providing an API layer and software as a service. I'd take a look at how Twitter, Facebook, or Google expose their APIs for other applications to use. Typically, there is a secret key and application ID involved in authenticating the REST calls.
I am in the process of looking at an API and I see the following two calls:
API.Users.Roles.getAllRoles();
API.Admin.Roles.getAllRoles();
What I would like to know is how each of these call is used within
the context of a Web program. Since both Admin and Users are properties,
what exactly is the get; set; doing? How does the call know which Admin
(or user) is making the call?
My hunch is that this has something to do with how the API class is
instantiated (and session?) but I'd appreciate a walk-through on what is
going on here so I fully understand it.
The (abbreviated) class structure looks like the following:
public class API()
{
public Admin Admin { get; private set; }
public Users Users { get; private set; }
}
public class Users
{
public Roles Roles { get; private set; }
...
}
public class Roles
{
public override string[] GetAllRoles()
{
...
}
}
Thanks in advance.
It will check the current user name from the current principal (HttpContext.Current.User.Identity.Name) which uses forms/windows account depending on setup, or if not in the web environment, it will use the current windows user logged into the system.
To me it seems that they have a custom role provider and are therefore overriding the GetAllRoles method so that the roles can be obtained from the datasource. Without seeing further details, I can only assume, but when a user registers, they're probably assigned a particular role. They can then use the Roles.IsUserInRole method to detect what role the user is assigned to. There's more on custom role providers here which will explain why methods are being overwritten.