In my master page I have:
MembershipUser thisUser = Membership.GetUser();
loggedInUserID = thisUser.ProviderUserKey.ToString();
thisUser gives me access to all the fields in aspnet_Membership.
I want a new field, isSubscribed for each user. I can use an SQL query to fetch the value fine, but I want to know if there is someway to modify the membershipuser object so it retrieves this value as well, so it is accessible from:
thisUser.isSubscribed.ToString();
Thanks for any help!
you will need to add the field to the Profile Provider
A description of the Profile provider can be found here.
http://msdn.microsoft.com/en-us/library/2y3fs9xs.aspx
here is an excerpt from the article
"The ASP.NET profile feature associates information with an individual user and stores the information in a persistent format. Profiles allow you to manage user information without requiring you to create and maintain your own database. In addition, the ASP.NET profile feature makes the user information available using a strongly typed API that you can access from anywhere in your application."
Membership is for identification and authentication. It is not good practice to hack your security for the sake of a meta property.
As mentioned, Profile is the proper place to store meta data and this would obviate the need for a custom MembershipUser.
If you need sql query access to the data use the SqlTableProvider
Si Robinson gave a good answer for storing additional meta data against users without having to change the underlying schema but if you already have data stored about this user in your custom database schema, that won't quite work out.
The solution I have used is to implement my own membership provider:
http://msdn.microsoft.com/en-us/library/f1kyba5e.aspx
And then you can implement your own MembershipUser which exposes the IsSubscribed property.
This works fine with the Membership process within ASP.NET such as the login components. All you need to do is cast the object returned by GetUser() to your custom implementation and you are set!
You could use roles for this and assign users to a Subscriber role. Such as:
Roles.AddUserToRole("Bob", "Subscriber");
You're gonna have a real un-fun time querying by profile fields. With a role you will be able to enumerate users with:
Roles.GetUsersInRoles("Subscriber");
And you'll be able to add these roles to Web.Config files to control which parts of the site only Subscribers can see. Possibly better than wrapping content with a conditional based on a profile field.
Related
Good Morning,
I have a simple query, I am using firebase Authentication as a sign-in/ signup method to my flutter app, what is the right method if I want to store additional data, such as name, age and etc...
If you look at the class User that is defined in User.dart for instance that ships with the Firebase SDK for Flutter, you'll see various properties of the User class, including but not limited to:
String? get displayName
String? get email
bool get emailVerified
bool get isAnonymous
UserMetadata get metadata
You might see the metadata property and think Aha! Maybe I can put my extra data there, but if you look at that class' properties and code you'll soon realize that it's not going to allow you to store additional properties in it either.
So the User in Firebase is not the right place to store additional information about that user itself! That's the take-away I want you to get from this answer.
The right way to go about doing this is to store your additional information per user inside your Firestore Database. Create a simple collection and name it something along the lines of UserInfo and in there per user-id, store the additional information that you need per user, and add a field to every object in that collection named user-id and store the user.id in that field. That way you can always do a look-up of user information per user.id.
As i understand your problem to store additional data of a user after login. For this you can use Firestore database and create collections for the fields like- name, age and etc...
https://pub.dev/packages/cloud_firestore
Have a look into this library.
https://medium.com/firebase-developers/cloud-firestore-basics-in-flutter-68c7ec42eeca
To understand firestore go through this article.
I followed some tutorials about symfony and I just set my users. For technical reasons I cannot use FOSUserBundle yet.
I so have a User entity with credentials : username, plainpassword and password, and I now want to add profile data, such as name, mail, favourite colour, nail length and so on.
In the Symfony documentation, they put the email inside the user provider, but it's not used as credential there.
I wonder now, should I put all my profile data inside the user provider, or should I create a UserProfile entity with name, mail, coulours, etc fields with a One-to-One relationship with Users ?
If one is a bad practice, why ?
I don't think any of your solutions is a bad practice or wrong.
I would prefer putting everything in the User entity if most of my users will have profile data, so there will not be much null fields.
If only some users will have profile data, than I think it is little bit cleaner to make separate entity for UserProfile.
Question No 1
I am familiar with role management, a particular member in a particular role can do this and access this functionally. What I need to do is Manage individual user, not the role he is in.
For example, lets say I create a role, called "Sales". I setup the role permission what the sales persons can do. Now i want to keep a check on individual user. For example if this is "john", i want to show him the records only he created. If his is peter, I want to show him only that records which he created, not by john or other sales people.
Is there a thing called "User Management" in ASP.NET that we can use? If not we have to create it ourselves and I believe the integration with ASP.NET "Role Management" will not be that smooth.
Question No 2.
I am using control for user login. I want to create a session at this time so I can keep track of which user is signed in so I can show him the records only pertaining to him. How can I do that?
Your Q1 isn't really about Role vs User management (ie: authorizations) at this point. It's about audit tracking within your application.
And the way you do that is you capture the ID of the user who created the record in question with the record, so that later you can filter on that ID.
Pseudo database structure
Table Sales
Field...
Field...
Field...
CreatedByUser int not null, -- Populate this on creation and never change it again
ModifiedByUser int not null - populate this on every row update including insert
See ASP.NET Profile Properties.
Assuming the records in the database correspond to a unique ID for a user, you can store the unique id in a profile property per user.
1) If you want to filter records by the creating user, you need to record in your table the ID of the user who created the record. You can access the name of current user through User.Identity.Name and their ID (provider-dependent) through User.ProviderUserKey.
2) Sessions are created automatically in ASP.NET and provided you have a properly configured MembershipProvider, you can retrieve all the needed user info using the User object as shown above.
It sounds like you are a little unfamiliar with ASP.NET Membership and Roles capabilities, because they are actually set up quite well to accomplish what you are describing. I would recommend checking out this tutorial series:
https://web.archive.org/web/20211020202857/http://www.4guysfromrolla.com/articles/120705-1.aspx
You are talking about Authentication and Authorization. For question 1 you and implement a custom authorization provider to allow for user level control http://msdn.microsoft.com/en-us/library/aa479048.aspx For question 2, once you log in and are Authenticated, the session contains a userprinciple object that has the info in it automatically.
Using ASP.net, is there a recommended best way to access a particular field of the profile in code. I was looking in my old Problem-Design-Solution 2.0 book, and it does it by pulling all members in the DB and then iterating through each one's profile (see code below). Is there a better way?
for each (MembershipUser user in Membership.GetAllUsers())
{
ProfileCommon userProfile = profile.GetProfile(user.UserName);
if (userProfile.mysetting == desiredValue)
{
//do something
}
}
Edit 1
I found that it can be done a little more efficiently than pulling members and then pulling profiles. It is possible that not all members have a profile, so if you use the following code, you'll pull all the profiles (which may be fewer in number than members, and then can iterate across it:
for each (ProfileInfo theProfile in ProfileManager.GetAllProfiles (ProfileAuthenticationOption.All)
{
ProfileCommon pc = ProfileBase.Create(theProfile.UserName)
if (pc.mysetting == desiredValue)
{
//do something
}
}
It still round trips the DB for each profile, but it may not do it as many as if we used the members...
With built-in Profiles, no there isn't a better way. One option as provided by Tim is Table Profile provider or writing your own profile provider.
Or you can go completely other route i.e. storing profile information in your own custom table.
You could use the Table Profile Provider and build custom queries to get your desired settings.
You could probably do better with linq, I don't have VS with me right now, but pseudo code would look something like this:
var users = from MembershipUser user in Membership.GetAllUsers()
where user.mysetting == desiredValue
select user
then iterate over the users,
foreach(MembershipUser u in users) {
// do something
}
that should only contain the ones of interest. Linq should handle executing the SQL for you correctly, but you can check to see what it's doing with profiler.
EDIT
Actually that probably won't get you anything from a performance perspective, the GetAllUsers is going to bring back everything. You might want to create a linq2sql dbml map for the users table and use that instead of Membership class for querying against a custom property.
EDIT 2
ASP.NET Roles and Profiles: best way to query for collection of users who match custom profile property?
If you're using the table profile provider you may be able to use the linq query against that table:
http://weblogs.asp.net/kencox/archive/2010/09/05/using-the-sql-table-profile-provider-in-asp-net-4-web-applications-c-amp-vb.aspx
I have an .aspx form with 20 fields that must be disable based on a users role and a status of a order record. Currently the application has 5 roles and 3 status, so I have 300 different possible conditions that I have to account for.
My first thought is to store each permutation in a table, then set the fields when the page loads by looping through the fields. Is there a better way? Please note, I am using .Net 2.0 and NOT MVC.
I'd probably store the details of each field, and then the roles and status that can edit them, and do it that way.
What are the rules for the system? Basically, are there really 300 possible conditions? Or is that really certain fields are only editable for certain status, and then only certain roles can edit those fields? Or is it that certain fields are available for certain roles as well?
If it's more of the former I'd probably have something like this:
Three primary tables (makes it easy to extend if you add a field, role or status):
Fields
Roles
Status
Then two link tables:
Field.Id and Role.Id
Field.Id and Status.Id
Then for any given order and user you can then find which Fields are editable for the order's current status, and the users role, and as you work through the fields set the access rights appropriately - however you set the controls - either dynamically generating them based on the collection you get back, or statically on the page.
If you have an issue where the Role can override the Status, you could also store a boolean in the Field/Role table, indicating whether the Field should be avaiable regardless of status.
Like another responder, we also use a Business Object framework called CSLA. CSLA implements field-level security checks by requiring class developers to do security checks in the property get/set calls. A typical property implementation looks like this:
Private mFirstName As String = ""
Public Property FirstName() As String
<System.Runtime.CompilerServices.MethodImpl(Runtime.CompilerServices.MethodImplOptions.NoInlining)> _
Get
CanReadProperty("FirstName", True)
Return mFirstName
End Get
<System.Runtime.CompilerServices.MethodImpl(Runtime.CompilerServices.MethodImplOptions.NoInlining)> _
Set(ByVal value As String)
CanWriteProperty("FirstName", True)
If value Is Nothing Then value = ""
If Not mFirstName.Equals(value) Then
mFirstName = value
PropertyHasChanged("FirstName")
End If
End Set
End Property
Notice the calls to CanReadProperty and CanWriteProperty. The second parameter specifies that the method should throw an exception if the user is not authorized to perform the specific read/write operation.
The implementation of the CanReadProperty and CanWriteProperty are provided by the framework's base class but should be reproducible without adopting the entire CSLA framework. The implementations check an AuthorizationRules data structure which defines who is allowed/denied Read/Write access based on roles. Often, the AuthorizationRules structure is populated during object creation.
Exposing the same CanReadProperty and CanWriteProperty methods to your presentation-tier allows you to enable/disable UI elements based on the current user's access rights. For example:
FirstNameTextBox.ReadOnly = Not CanWriteProperty("FirstName", false)
Hopefully this information will provide you with a good starting point for developing your own implementation. If you're interested in learning more about CSLA then check out Expert C# 2008 Business Objects.
I suggest to use third party framework to achieve this. We use CSLA framework in our projects. It allow us to set authorization at field level.