 |
BOOK: Beginning ASP.NET 2.0 BOOK VB ISBN: 978-0-7645-8850-1; C# ISBN: 978-0-470-04258-8  | This is the forum to discuss the Wrox book Beginning ASP.NET 2.0 by Chris Hart, John Kauffman, David Sussman, Chris Ullman; ISBN: 9780764588501 |
|
Welcome to the p2p.wrox.com Forums.
You are currently viewing the BOOK: Beginning ASP.NET 2.0 BOOK VB ISBN: 978-0-7645-8850-1; C# ISBN: 978-0-470-04258-8 section of the Wrox Programmer to Programmer discussions. This is a community of software programmers and website developers including Wrox book authors and readers. New member registration was closed in 2019. New posts were shut off and the site was archived into this static format as of October 1, 2020. If you require technical support for a Wrox book please contact http://hub.wiley.com
|
|
|
|
|

March 5th, 2009, 06:01 PM
|
|
Registered User
|
|
Join Date: Mar 2009
Posts: 4
Thanks: 1
Thanked 0 Times in 0 Posts
|
|
questions on Membership and auto login
Hi, Your book is great and it has helped me get a very basic shopping cart setup for our extranet users to purchase literature. The order gets processed in a backend Oracle process that reads from a sql table the items ordered. Billing is handled from Oracle.
However, i am having a problem. My users are already authenticated on our extranet website, which is non-asp.net website (Eprise). I have set up my Shopping Cart app on a separate virtual directory using asp.net 2.0 and vs 2008. i want to use the membership and profiles to manage the cart. I don't want my users to have to login again. I have an api that I can put on my pages that forces them to login to my original if they are not logged in. I want to pass the loginid from the original site to the Shopping Cart site and have that id used as the Username in Membership.
I cannot figure out how to automatically login the user in regards to membership and profiles. I can validate the user and create him if he does not exist, but how do I log them in without presenting a login page?
Any help would be appreciated.
|
|

March 5th, 2009, 08:04 PM
|
|
Wrox Author
|
|
Join Date: Oct 2005
Posts: 4,104
Thanks: 1
Thanked 64 Times in 64 Posts
|
|
The simple answer is that you can't do ths directly.
The detailed answer goes like this: to achieve this you are going to need to implement somewhat of a hack (more a work around really) and you will have to implement it on both applications.
*Note: I make the assumption that both applications fall within the same domain
On both .NET and Eprise website you will want to modify how the application determines if a user is logged in or not. For example, lets say that on the .NET side our logic goes soemthing like this:
c# Code:
if(Session["somevalue"] != null) { //user is logged in } else { //user is not logged in redirect }
This will work like a charm all throughout your .Net application but not your Eprise site (obviously). So a solution would be to create both a session value AND a cookie when the user logs in. Now, the code in the previous section looks something like:
c# Code:
if(Session["somevalue"] == null) { if(<cookie> != null) { //do work //user is logged in } else { //user is not logged in; redirect; } } else { //user is logged in }
Now your first thought maybe to just store something like the User's ID from the database in the cookie or maybe the User's login name; don't do this! The reason you wouldn't want to do this is because it becomes a trivial matter to spoof your Applications into thinking im someone im not. A better solution may be to populate the cookie with a GUID which makes it a bit more difficult to spoof your application.
So what does the GUID correlate to? The guid should be tied to a record in a database table that indicates that XYZ user has been authenticated and is logged into the website.
So now your code snippet might look like so:
c# Code:
if(Session["somevalue"] == null) { if(<cookie> != null) { //Select record from database where CookieGuid = TableGuid if(<database result> != null) { //User is valid and logged in Session["somevalue"] = <database result> } else { //User is not logged in; redirect } } else { //user is not logged in; redirect; } } else { //user is logged in }
To prevent myself from having to continually call this code over and over, I would probably create a base class object that all of my web pages could inherit from and run this code from there.
Some considerations:
-I would add an expired field to the database table so that you could eliminate records as they become expired. This is to keep the size of the database manageable and also to prevent someone from gaining access to the system via an outdated record. To this end you will need to create a call that will continually update this expired column everytime the user makes a page request to indicate that they are still logged in. You can then safely delete rows where expired is <= Now - 30 mins or something similar
-Set your cookies to expire once the browser session is over.
-Remeber Me functionality. If your application employs this type of feature you will need to modify your code a bit more so that it makes an additional check:
c# Code:
if(Session["somevalue"] == null) { if(<cookie> != null) { //Select record from database where CookieGuid = TableGuid if(<database result> != null) { //User is valid and logged in Session["somevalue"] = <database result> } else { //User is not logged in; redirect } } else { //user is not logged in; redirect; } } else { if(<cookie> == null) { //populate cookie } //user is logged in }
this will ensure that if the user didnt come from the login page that the cookie is still being set.
Does this help you?
hth.
-Doug
__________________
===============================================
Doug Parsons
Wrox online library: Wrox Books 24 x 7
Did someone here help you? Click  on their post!
"Easy is the path to wisdom for those not blinded by themselves."
===============================================
|
|

March 9th, 2009, 02:57 PM
|
|
Registered User
|
|
Join Date: Mar 2009
Posts: 4
Thanks: 1
Thanked 0 Times in 0 Posts
|
|
Doug,
Thank your for your reply. The way that my extranet API is set up, it pretty much handles this for me just like you indicate. I can prevent uses from accessing the shopping cart application with a plugin API from my extranet.
My shopping cart app and the extranet are in the same domain.
What I am not clear on is how to I utilitize this with Membership/Profile piece of asp.net, or if I can.
I have the user authenticated, I know his account information from my other system, but I want to use the Membership and profile information to keep track of the users shopping cart and billing/shipping information.
How do I associated a user, based on his login id from my other site, with his profile/membership in .net?
I can go ahead and use anonymous, but that tracks users based on the IE information. If an individual logs into my extranet and builds a shopping cart and then sa econd user comes along on his machine and logs in with a different extranet user account and goes to the shopping cart, the second user sees all of the first users shopping cart and information. Now, I realize people probably shouldn't be letting others use thier machines, but is it bound to happen in our situation. I am trying to prevent confusion by tying the membership and profile information the users login ID from extranet system.
I hope I am being clear on this. I am fairly new to writing .net web apps and this is the first time I am using the Membership/Profile piece in .Net.
Thank you for all your help!
|
|

March 9th, 2009, 03:28 PM
|
|
Wrox Author
|
|
Join Date: Oct 2005
Posts: 4,104
Thanks: 1
Thanked 64 Times in 64 Posts
|
|
Oh, thats easy enough. You should be able to just do this:
csharp Code:
FormsAuthentication.SetAuthCookie(<username>, false);
This will bypass, obviously, the check to the membership system to make sure that the user credentials are valid. You could integrate that however by doing something like:
csharp Code:
if (Membership.ValidateUser(<username>, <password>)) { FormsAuthentication.SetAuthCookie(<username>, false); } else //do something
hth.
-Doug
__________________
===============================================
Doug Parsons
Wrox online library: Wrox Books 24 x 7
Did someone here help you? Click  on their post!
"Easy is the path to wisdom for those not blinded by themselves."
===============================================
|
|

March 9th, 2009, 05:08 PM
|
|
Registered User
|
|
Join Date: Mar 2009
Posts: 4
Thanks: 1
Thanked 0 Times in 0 Posts
|
|
Doug,
I tried this:
Code:
If Membership.ValidateUser(Session("LoginID"), "Chiller_01") = FalseThen
Membership.CreateUser(Session("LoginID"), "Chiller_01")
FormsAuthentication.SetAuthCookie(Session("LoginID"), False)
Else
FormsAuthentication.SetAuthCookie(Session("LoginID"), False)
EndIf
Profile.LoginID = Session("LoginID")
But I am getting this error:
Exception Details: System.Configuration.Provider.ProviderException: This property cannot be set for anonymous users
Stack Trace:
[ProviderException: This property cannot be set for anonymous users.] System.Web.Profile.ProfileBase.SetInternal(String propertyName, Object value) +192 System.Web.Profile.ProfileBase.set_Item(String propertyName, Object value) +73 System.Web.Profile.ProfileBase.SetPropertyValue(St ring propertyName, Object propertyValue) +8 ProfileCommon.set_LoginID(String Value) +14 ShoppingCartPage.Page_Load(Object sender, EventArgs e) +308 System.Web.UI.Control.OnLoad(EventArgs e) +80 System.Web.UI.Control.LoadRecursive() +49 System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +3750
So it is not letting me set the Profile Property LoginID, and I am assuming any other profile property. Here is the web.config info.
Code:
<identity impersonate="false" />
<membership>
<providers>
<remove name="AspNetSqlMembershipProvider"/>
<add name="AspNetSqlMembershipProvider"
type="System.Web.Security.SqlMembershipProvider, System.Web,
Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
connectionStringName="LocalSqlServer"
enablePasswordRetrieval="true"
enablePasswordReset="false"
requiresQuestionAndAnswer="false"
applicationName="/"
requiresUniqueEmail="false"
passwordFormat="Clear"
maxInvalidPasswordAttempts="5"
passwordAttemptWindow="10"
/>
</providers>
</membership>
<profile enabled="true">
<properties>
<add name="LoginID" />
<add name="RepNumber" />
<add name="ShipName" />
<add name="ShipAddress" />
<add name="ShipCity" />
<add name="ShipState" />
<add name="ShipZip" />
<add name="ShipPhone" />
<add name="BillName" />
<add name="BillAddress" />
<add name="BillCity" />
<add name="BillState" />
<add name="BillZip" />
<add name="BillPhone" />
<add name="ContactName" />
<add name="CostCenter" />
<add name="Cart" serializeAs="Binary" type="McQuayBiz.Commerce.ShoppingCart" allowAnonymous="true" />
</properties>
</profile>
<anonymousIdentification enabled="true" />
Any ideas?
I really appreciate your help.
Mark
|
|

March 9th, 2009, 11:23 PM
|
|
Wrox Author
|
|
Join Date: Oct 2005
Posts: 4,104
Thanks: 1
Thanked 64 Times in 64 Posts
|
|
I could be wrong on this (I dont use the membership stull all that often) but I believe the problem you are having is that, even though you are setting the Auth cookie in a previous line, the user still isn't in a "logged in" status.
I think if you did something like this:
csharp Code:
ProfileCommon p = (ProfileCommon) ProfileCommon.Create(<username>, true); p.LoginID = <value>; p.Save();
I would probably advise against this since, obviously, a profile would be created for a user everytime they accessed the stie regardless if they already had one or not. AFAIK there is no check you can do to see if a user already has a profile setup (again I could be wrong).
What I think I might do is expand upon your API so that when a user registers on your other site it would make a call to said API that would then take care of creating the asp.net user, profile, etc so then all you have to do is:
If Membership.ValidateUser(Session("LoginID"), "Chiller_01") = FalseThen Membership.CreateUser(Session("LoginID"), "Chiller_01") FormsAuthentication.SetAuthCookie(Session("LoginID"), False) Else FormsAuthentication.SetAuthCookie(Session("LoginID"), False) End If 'Redirect somewhere Response.Write(Profile.LoginID)
hth.
-Doug
p.s. the Last line is a bit redundant since you could do something like: HttpContext.Current.User.Identity.Name to get the current users name.
__________________
===============================================
Doug Parsons
Wrox online library: Wrox Books 24 x 7
Did someone here help you? Click  on their post!
"Easy is the path to wisdom for those not blinded by themselves."
===============================================
Last edited by dparsons; March 9th, 2009 at 11:25 PM..
|
|
The Following User Says Thank You to dparsons For This Useful Post:
|
|
|

March 26th, 2009, 10:40 AM
|
|
Registered User
|
|
Join Date: Mar 2009
Posts: 4
Thanks: 1
Thanked 0 Times in 0 Posts
|
|
I got it working
What you posted worked fine, as long as I set my web.config windows authentication to "Forms" vs "Windows". Duh! Without doing that, the user was always anonymous.
This is my code: Note: I had to use a default password for all users (shown in the code as "xxxx".)
Code:
Dim m_oEprUser AsObject
If Session("LoginID") IsNothingThen
'Call my external API for Authorization
m_oEprUser = authorize_user()
'Check if user is Authenicated
If User.Identity.IsAuthenticated = FalseThen
'If not, then Validate user exists
If Membership.ValidateUser(Session("LoginID"), "xxxx") = FalseThen
'If not, create the user
Membership.CreateUser(Session("LoginID"), "xxxx")
'Remove any possible anonymous cookies
Response.Cookies.Remove(FormsAuthentication.FormsCookieName)
'Set the Authentication
FormsAuthentication.SetAuthCookie(Session("LoginID"), False)
Else
'If user does exist, Authenticate them
Response.Cookies.Remove(FormsAuthentication.FormsCookieName)
FormsAuthentication.SetAuthCookie(Session("LoginID"), False)
EndIf
'Reload Page
Response.Redirect("shoppingcartpage.aspx")
EndIf
EndIf
Thanks for all your help!
Now if I can figure out how to get the shopping cart web grid to enable edit for all rows with a batch update I will be really rockin'.
Any posts or ideas on this anywhere that you know of?
Thanks again!
|
|
 |