Is it possible to access a profile without updating LastActivityDate? - asp.net

In asp.net (using MVC, but this happens in regular too)
Profile.GetProfile(username);
will update the LastActivityDate for that user. This is not intended when someone else is viewing that user's profile.
In the membership class you can specify whether to update this date with a second param, like so:
Membership.GetUser(username, false); // doesn't update LastActivityDate
Membership.GetUser(username, true); // updates LastActivityDate
Is there anyway to do something similar in the Profile provider without writing my own provider?

You might use one ugly workaround which includes changing aspnet_Profile_GetProperties stored procedure. This one is responsible for getting the properties while accessing user profile.
Open this procedure and you will find following code at the bottom:
IF (##ROWCOUNT > 0)
BEGIN
UPDATE dbo.aspnet_Users
SET LastActivityDate=#CurrentTimeUtc
WHERE UserId = #UserId
END
Remove it in order to stop updating the LastActivityDate. You will still get LastActivityDate updated when calling Membership.GetUser(username, true);.

You might look at using a provider that someone else has written, rather than write your own.
This one on Scott Guthrie's blog includes stored procedures which could be called directly by your own code to get the information:
http://weblogs.asp.net/scottgu/archive/2006/01/10/435038.aspx
This page has an msi download which installs a sample application for working with custom Profile data. The table based profile performs a lot better than the default on, where all of the profile data is contained in a single database field. The table based one is also a lot easier to query directly, which will help you with your question. The stored procedure from the sample schema is called getCustomProfileData
Otherwise, just query the database directly.

Related

Storing Temp. Data in ASP.NET Core (NopCommerce)

Dear StackOverflow community,
For a project of mine I need to store (Temporary) data somewhere else than a Database. Actually its a little more complicated. I have a checkout page in NopCommerce where users can select them delivery moment or even location for example pickup. This data has to be store temporary untill the user made the payment. Only then I will request the data and store in DB. So that later I can retrieve the data and display in my dashboard, So that I know when the package is scheduled to be shipped.
Requirements:
Endurement: 12-24 Hours.
Store as user specific data.
Data has to be safed for quite a few sessions. Depends on the user. For example. If the user chooses a delivery moment but desides to look somewhere else before paying. This data has to be stored all those sessions.
If possible serverside.
I have quite a few options following Microsoft:
Session and state management in ASP.NET Core
Now I have tried storing data in Memory (Caching data) using 'MemoryCacheEntryOptions'. The problem is that its application wide. And its hard to maintain with hundreds of users.
Other option is 'Session state'.
The problem is that this data only endures a single session. I need to hold the data for atleast 12 to 24 hours.
Then we have 'Temp Data'. This seems like a promising option. Its great since it is kept until the is has been used/read. You even have 'Peek' and 'Keep' Methods to keep the data while peeking. Problem: It requires a controller. And requesting the data is a callback Method that doesnt require a Controller.
'Query Strings' Well its not much is it? This may be not user critical data BUT seems like query string isnt what Im looking for.
'Hidden Fields' Not really suitable either. It is therefore not form data.
'HttpContext.Items' Definetly not suitable. Data is only stored for single request.
'Cache' Way to hard to maintain user specific data.
So my question is. How do I save all this data temporary, if possible server side for a day atleast with hundreds of users at the same moment. And request the data later in a callback, to store it in DB until the order is shipped.
NopCommerce exposes a class called GenericAttributeService in Nop.Services.Common. This allows you to store your custom attribute data, specific to each customer.
To use it, first inject the GenericAttributeService into your class (controller, service class, etc).
private readonly IGenericAttributeService _genericAttributeService;
public MyFancyController(IGenericAttributeService genericAttributeService)
{
_genericAttributeService = genericAttributeService;
}
To save the data for current customer, use SaveAttribute and save an key-value pair you need:
_genericAttributeService.SaveAttribute<string>(_workContext.CurrentCustomer, "MyKeyName", "Value to save for this customer")
_genericAttributeService.SaveAttribute<int>(_workContext.CurrentCustomer, "My2ndKeyName", model.id)
To get the data use GetAttributesForEntity, where the entity is your key value.
var attribute = _genericAttributeService.GetAttributesForEntity(_workContext.CurrentCustomer.Id, "Customer").Where(x => x.Key == "MyKeyName").FirstOrDefault();
To delete the attribute use DeleteAttribute:
_genericAttributeService.DeleteAttribute(attribute);
Notice that we used _workContext which helps expose the current customer.
This already works well with other temp functionality already existing in the application, such as managing shopping carts, wish lists, etc, so browsing the source code for other examples can also be helpful.

Entity Framework table updates not working due to trigger calling CLR

I have a table with a trigger that points to an assembly:
CREATE TRIGGER [dbo].[triggername] ON [dbo].[tablename]
WITH EXECUTE AS CALLER
AFTER DELETE, UPDATE
NOT FOR REPLICATION
AS EXTERNAL NAME [Namofassembly].[blahblah].[blahblah]
We also using code first EF in .net 4.
When I use delete everything works fine but the trigger does not get called.
dataRepo.UsersPermanentAuditAssignments.Remove(isInsertFound)
When I use update I get a permissions error. This is either when I try it through the object model or a dataRepo.Database.ExecuteSqlCommand(updateSql)
System.Data.SqlClient.SqlException: The context transaction which was active before entering user defined routine, trigger or aggregate "name" has been ended inside of it, which is not allowed. Change application logic to enforce strict transaction nesting.
Everything works fine when I run the queries via the sql management studio.
I also am not able to change this configuration so while I don't care for this design I am not able to change it.
My questions are:
1> Why would the delete not get logged but work?
2> Do I need to add something extra to my repo configuration object that will allow this to work? Do I need to add some transaction like unitofwork before I start this since it has a trigger maybe?
I have figured out the causes of this issue.
It relates to having a composite primary key (station,user) and trying to update one of the values.
I could not update any column of the primary key, ie change the user assigned to a station.
The trigger failure masked the issue of not being able to update a value inside the key.
My experiments show the following for the compositekey/pk update:
Method History Trigger Result
EF.SaveChanges Enabled Fail at trigger
EF.SaveChanges Disabled Fail at trigger
EF.ExecuteSQLCommand(sql) Enabled Fail at trigger
EF.ExecuteSQLCommand(sql) Disabled Works
Unfortunately, I don't have the ability to change to a surrogate with a unique index which would work. Also, the trigger CLR prevents me from using DataBase.ExecuteSQLCommand(sql) also which I believe is actually a problem with the CLR of which I have not ability to modify.
So my advise (that I can't take) is if you get this use a surrogate key and a unique index instead of combining the 2.
If anyone knows any way to allow EF to allow you to change a value inside a composite/primary key please comment.

avoid sql inject by query string in asp.net

I programed an application with asp.net and use "respons.redirect" in some pages, like this:
Response.Redirect(string.Format("~/*****/****.aspx?ID={0}", ID));
as user execute this cod he will redirect to correct page and every thing is fine .he can see this redirect link in his browser address :
http://localhost:1852/Jornal/Editor/ReviewerEmail.aspx?ID=1030
Now if he changes the ID manually and the ID is correct he can access the other data without any permission. how can i avoid this problem?(I wont use session)
please help me
If the ID needs to be public and no access control can solve the problem.
then i would suggest that you add a second parameter that is a hash of that Id.
Tampering with the ID parameter will cause a missmatch between ID and hash
http://msdn.microsoft.com/en-us/library/system.security.cryptography.sha256.aspx
you cold also change your ID parameter to a less 'guessable' id, like a GUID
You need to use access control.
Whenever you display any data, you need to check whether the currently-logged-in user has access to that data.
Obviously, you also need to track the currently-logged-in user, in a way that will prevent attackers from being able to claim they are someone else..
To do that, use ASP.Net's built-in membership system.

Security Issue with ASP.NET and SQL Server

A problem appears when two users are logged on to our service system at the same time and looking at the service list gridview. If user1 does a search to filter the gridview and user2 happens to click to another page user2 sees the results from the search performed by user1. That means one company can see another company's data.
It's an ASP.NET application that was developed in house with C#/ASP.NET 3.5. The data is stored in a SQL 2000 database and relies very heavily on stored procedures to update, select, and delete data. There are multiple user types that are restricted to what data they can see. For example, we have a company use that can only see data relavant to that company.
From what I've seen, the security is handled through If statements in the front end. Example, if userlevel = 1 then do this, if userlevel = 2 do this. These statments are used to show or hide columns in a grid, run queries to return data, and any other restrictions needed. For a company user the code behind gets the companyid assigned to the user and uses that in a query to return the results of all the data associated with that companyid (services, ships, etc).
Any recommendations for fixing this will be highly appreciated.
It's hard to say without seeing any implementation details, but on the surface it appears that there maybe some company level caching. Check for OutputCache settings, DataSource caching, explicit caching with Page.Cache, etc.
This article is a little dated, but at a glance it looks like most information is still relevant in ASP.NET 4.0.
ASP.NET Caching: Techniques and Best Practices
In addition to jrummerll's answer, check the Data Acces Layer of our app and make sure that you don't have any static variables defined. Having a static variable defined could cause this sort of issue too, since 2 contending requests may overwrite the value of the CompanyID, for example.
You basic model should work. What you've told us is not enough to diagnose the problem. But, I've got a few guesses. Most likely your code is confusing UserID or CompanyID values.
Are you mistakenly storing the CompanyID in the Cache, rather than the session?
Is the CompanyID stored in a static variable? A common (and disastrous!) pitfall in web applications is that a value stored in a static variable will remain the same for all users! In general, don't use static variables in asp.net apps.
Maybe your db caching or output caching doesn't vary properly by session or other variables. So, a 2nd user will see what was created for the previous user. Stop any caching that's happening and see if that fixes it, but debug from there.
Other variations on the above themes: maybe the query is stored in a static variable. Maybe these user-related values are stored in the cache or db, but the key for that record (UserID?) is stored in a static variable?
You can put that if statements in a thread. Threading provides you the option that only 1 user can access the application or gridview in your case.
See this link: http://msdn.microsoft.com/en-us/library/ms173179.aspx
Here is some sample code that is throughout the entire application that is used for filtering results. What is the best way to fix this so that when one user logs on, the other user doesn't see those results?
protected void PopulategvServiceRequestListing(string _whereclause)
{
_dsGlobalDatasource = new TelemarServiceRequestListing().GetServiceRequestListingDatasource(_whereclause);
if(_dsGlobalDatasource.Tables[0].Rows.Count!=0)
{
gv_ServiceRequest.DataSource = _dsGlobalDatasource;
gv_ServiceRequest.DataBind();
}
else
{
gv_ServiceRequest.DataSource=new TelemarServiceRequestListing().DummyDataset();
gv_ServiceRequest.DataBind();
gv_ServiceRequest.Rows[0].Visible = false;
gv_ServiceRequest.HeaderStyle.Font.Bold = true;
}
}

which database will I use with Sys.Services.AuthenticationService.get_isLoggedIn()

I read this article and examine source code. But I cant understand that which database have he used.
And I have a database and table named "users" and field of "username" and "password" and "roles". So I want to use Sys.Services.AuthenticationService.get_isLoggedIn().
And I cant understand how reach my database and query recorded user and return answer..
Can u give same example..
thanks..
MSDN :
Sys.Services.AuthenticationService.get_isLoggedIn: The value of
this property is set by the ScriptManager object during a page
request.
So, if my understanding is good, this value should be the same as HttpRequest.IsAuthenticated property. You just have to do normal authentication in server side code (using ASP.NET membership or FormsAuthentication) to automatically have this property set.

Resources