Add Session Management to ASPX pages with Minimum Code Changes - c#

I have an ASP .NET application which has a number of aspx pages. These pages were not having any login or session management features and any user could directly type the url and visit any page.
Now I want to add state management feature to all the pages. I created a new signup and a basic login page which accepts username and password and has necessary database for it. It is fine to use any server or client state management features, but how can I implement it with very minimum code changes.
One straight forward solution here is to implement session variable in server side to store logged in user details and check for it in the Page_Load event handler of each and every page. But here, code change has to be made in all the pages and I don't want that as there are so many pages. Any easier way will help.
Any ideas please??

Well, first of all it was good that you haven't implemented authentication in Page_Load on every page. Whenever approach you think of requires that you copy-paste code in multiple places - you are doing something wrong.
That being said, you will probably need to create base class for your Pages and by doing that you could have authentication restricted to one spot / class.
However, it would be better if you combine that with what ASP.NET framework offers. From stuff you are talking about it seems you are using ASP.NET Forms - here is article that should provide you with fine overview on everything you need to do:
How to modify web.config to use Forms authentication
Login and Logout user (create authentication cookie)
Necessary code for authenticating requests that needs to be added to Global.asx
Restricting access to pages by entering appropriate values in web.config (although better approach would be with base class I mentioned)
Role-based Security with Forms Authentication

Related

Login via API (outside app) and create a cookie for access

Ok so I think I've settled on choosing BLAZOR for my upcoming project. But first I need to do something that is seemingly very basic.
For context, Blazor Server side will be how I interface with my SQL Server dB, I want "individual accounts" mode to be the way users authenticate. I'm using net 6.0,almost all tutorials out there seem to be net 5 since they all still have startup.cs files. Ok, but I also am creating a parallel app that is NOT a website, but I want it to grab data from the same database via routes after authenticating.
For example, website.com/api/data?variablestograb as a GET would send me some json data.
OK that being said, how do I login programmatically from an outside app? If you must know, the outside app is part of Unity C#. But that doesn't matter so much, what itll do is use a post call to login in via the api routes. Something like
Website.com/api/login?un=blah&pw=haha
This will generate a cookie and I can grab it with the session data and I'll use this with every get call hence.
Just using the basic templates, Blazor server net 6.0 with individual auth, how do I set up such a route? Looking at the files, I'm at a complete loss on how the login pages are actually passing data around.
Thanks!
Update: the specific ask is exactly how do I modify the Blazor Server Net 6 Individual Accounts template to allow me to authenticate a user via an external access api? My thought would be to reference the route above for /login/ but that might not even be the best practice. But even if it is, how exactly and where would I update the template to make this happen?
(I have a feeling it's pretty basic to do, but I've been reading tutorials for weeks now and they're all just talking about internal authentication and verification within each Blazor component. I basically want an external program to also be able to "drive the car" remotely, but first it must authenticate.)
If you're building an API for this from scratch, then it seems like you have the right idea, no matter what happens, you're going to send the cookie to be website every request or at least a session id which contains all the information provided. From a database perspective maybe create a session table which then contains all the info you want and also can be easily found. That's a way for you to create a cookie for client server communication, however this is from my limited knowledge and may not be the best way.
I'd recommend hiding information like keys in the header to prevent exposure, looking at other APIs like the Spotify API you can see they set the authorisation bearer.
Exposing all the information for the credentials in the URL for what could be sensitive database behaviour may not be the best. You can hide the information in the header for every request you make.
Maybe have a default controller that obtains the user information before handling any specific requests and making it accessible to your other methods/requests?
The basic process for any external authentication is:
Redirect to the external log in page.
External Provider does it business.
External provider posts to a page on your site with the authentication information included - normally security info in the header or a cookie.
The Blazor app reads the authentication information with the AuthenticationStateProvider.
Normally you just need to write a customer AuthenticationStateProvider and code to redirect if the user is not authorized. This may be a manual button in the top bar, a you aren't logged in page with a button to log in, or an automatic redirect to the provider. The return for the provider is either your landing page or some other page to tell them they logged in successfully.
The custom AuthenticationStateProvider replaces the standard one in DI services and provides the security information to the Authorization components.
Search for "blazor custom authentication provider" will get you lots of good resources.

asp.net c# web app with active directory and windows authentication

i'm currently developing an intranet web app, with a homepage and several departmental pages, the web app is merely for viewing information so everyone will have the same privileges. i've reached a point that i must worry about the app's access and authentication, my company has an active directory with several groups that i can use, after searching for a while i got the following questions:
in the webconfig file, i forced windows authentication and blocked users that are not authenticated (deny users = ?)
i saw somewhere that i need several webconfig files, one for each page, is that so? how do it make each page connect to the corresponding webconfig?
after looking at some examples i can't figure out my AD connection string (i'm currently on a development machine), our AD groups are on our domain controller, the physical location is "DCserver.company_name.local\city folder\groups"
do i need to create a login page? i mean doesn't that kinda go against the point of having windows authentication?
i don't need to manage anything within the AD, i simply want to read the groups and ensure that, for example, the marketing people only have access to the homepage and the marketing departmental page
as i've mentioned up there, there will be no special special privileges, the user from, for example, marketing will be able to click everything within his departmental page
i'm sorry for all the questions, but i'm relatively new to c# and .net development
Following are the answers to your latest set of questions:
-In the webconfig can i specify the groups that have access to each departmental page as well as the homepage? kinda like the following code, if so, i need my ldap connection string to be placed before assigning which groups have access to which page, right?
[Dipra] You are probably better off doing the authentication without using the roles in web.config, as this will also require the roles to be defined. We are talking about AD groups here, of which users will be a part. So, in the Page_Load(), simply call the authentication method, probably passing the username and the AD group allowed access to the page as parameters. If you want to make your solution configurable, store the allowed AD group for a particular page as 'keys' in your web.config and then read them in your code. Pass the group to your authentication method along with the username.
-when a user opens the web site, he will be prompted to insert his windows credentials, this is automatic, right? he will then be able to see the homepage and then go to his departmental page, right?
[Dipra] Yes, this is automatic. No separate code required for this. He can go to whichever page he wants, provided he is authenticated.
-if i understood correctly, in every page_load event i need to do a search taking the user's name and checking to which groups he belongs to, is that right?
[Dipra] Yes, you need to do that check in every Page_Load() method. As an approach, you can try getting all the groups of which the user is a part, and then check whether the allowed AD group for that page is one of those groups. If it is, the user can be authenticated.
-i the above is true, and now i'm gonna explain the navigation of the page 'cause i think that messing with the page_load might bring me some issues
will the check to see to which groups the user belongs to occur with every page load? won't that make the app slow?
[Dipra] Every server side control, e.g asp buttons, will cause a postback. To ensure the authentication code in Page_Load() doesn't run every time a postback happens on the page, enclose that bit in if(!Page.IsPostBack) {}. This means any code within this block will run when the page is not being 'posted back', i.e., being rendered for the first time. Any subsequent postbacks from server side controls on this page will ignore the code inside this block.
-finally, to check the membership of each user i need a similar code to the second answer on this The Link that Dipra posted i pasted below but in c#, right?
[Dipra] You can refer to the accepted answer on the above post, probably with a couple of tweaks of your own. It's already in C#.
Yes, your web.config would be like what you said.
You don't need to 'grant' access to specific groups for pages. In the web.config, store the groups allowed access to specific pages as keys and read the configuration in your code like this. For example, if you have a key named 'Marketing', then you can store the name of the corresponding AD group, which is allowed access to Marketing pages in the value field. Yes, once you have got it working for one page, others will be easier.
No, the authentication method that I talked about is a custom method you will write for yourself, which will use logic similar to the one in the link I had posted.
The entire authentication code should be enclosed in a try...catch block. If there are issues while doing the authentication against your AD (for e.g., connection problems), then your code will throw an exception. Catch (and ideally log) the exception and redirect the user to an error page, probably saying there were some problems which prevented authentication. You should not be granting access to the user in such a scenario.

ASP.NET Login, Authorization and Session Management Approach

I'm new to C# and ASP.NET (not MVC) and trying to code a web site.
Here is the question:
Which is the best approach for Login, Authorization and Session management? I'm not asking for how to use built-in membership classes or another ready-to-use solutions. I'm merely asking for a manual approach or methodology.
After a member writes User Name and Password and clicks submit button; which do you think is the best solution to keep user logged while he\she browses pages, clicks buttons or somehow interacts with the web site
E.g is it a good method to use Session and write the User Name, Id etc. to session and read the session in every page request to check if there's any member information; if so, set the page layouts according to member's preferences?
Or creating an object in login, setting it's properties according to logged in user and using same object for entire session and destroying it with logging out?
Thx
I suggest that the best approach is to use a pre-exisitng solution that has proven realiable.
For authentication, use a MemberShipProvider. If you don't want to use for instance the SqlMembershipProvider, feel free to implement your own by deriving from System.Web.Security.MembershipProvider. Then register you custom provider in the web.config file of your application.
To get started, just search the web for "build a custom membership provider" and you will find lots of tutorials.
For authorization, use the possibilities provided by the <authorization>...</authorization> section in web.config. Make sure to learn about the possibility of placing additional web.config files in sub folders of your application.
If you need role based authorization, use a RoleProvider. Related web search: "build a custom role provider".
If you want to allow your users to store preferences, use a ProfileProvider.
In short, resist the temptation of reinventing the wheel...

Set up STS but keep formsauthentication in webapp

I'm enabling an windows identity foundation on an existing webapp.
I want to mess as little as possile with the existing code so I would like to the login page which uses formsauthentication left in the application and I just connect with the STS if the user enters the application via a specific page e.g "im_comming_from_some_other_site.aspx".
in the "im_comming_from_some_other_site.aspx" the code would be like:
Page_Load(...)
{
if(verifyAgainstSTS()
{
FormsAuthentication.SetAuthCookie(<some_STS_Userid), ...)
Response.Redirect("default.aspx")
}
else
{
Response.Redirect("http://<STS_server_name/<STS_service...etc>")
}
}
Is there someone who knows if this may be done and how? Any links to example code (if available) deeply appreciated.
(Of course some code would be needed when to determine what to do when the authentication is timed out; either go to local login page or goto STS-login page)
I know this may seem like a bad design, not going all the way with STS, but I need to implement this ASAP and I want to keep the original site as untouched as possible.
It is not a bad design, it's your requirement and you try to fulfill it. We have working system built like that and it's not a rocket science. The only difference is that we switch it to forms/sam statically (via global settings), not dynamically.
Anyway, you keep your forms authentication in web.config so that when there's no authorization for current user, forms redirects the request to the login page.
In the login page you have two options. One creates the forms cookie somehow.
The other option involves WIF's FederatedPassiveSignIn control.
If a user follows forms authentication, the cookie is set and you are done.
If a user follows the STS login control, sooner or later he/she will come back with valid SAML token. The FederatedPassiveSignIn will pick it up automatically and you just handle the redirect in the SignedIn event.
You will even not need the if you mention in your question.
There's one caveat from what I remember. When a user is authenticated by STS, the WS-Federation cookie is created, you can read claims etc. Everything works.
However, if a user is authenticated by forms, the SAM (SessionAuthenticationModule) will REPLACE forms cookie by the WS-Federation cookie in ASP.NET pipeline upon EACH request (I guess it's because the SAM is later in the pipeline that forms authentication module).
This will NOT blow up your context.User.Identity.IsInRole(...) also authorization works correctly because SAM will copy user roles to corresponding claims.
However, if at any place in your code you try to extract information directly from the forms cookie (instead of using general APIs), you could find out that the forms cookie is not present even if the user was authenticated by forms in first place (and the cookie is not present because it will be replaced by the WS-Federation cookie).

Quickest way to require authentication in asp.net webform?

As of right now, I have the user register/log in and then if successful, redirect them to the homepage. However, this is extremely artificial as the user can simply type the url and go to any page they want. I'm fairly new to this and I've heard forms authentication mentioned multiple times as a way to do what I need: a simple means to prevent a user from accessing any page and once they haven't done a "Request" in awhile, I want them to be "logged out" and sent back to the log in page. I guess, in the end, I have three questions:
1) Can someone provide me a link to a great tutorial on authentication? I don't want to get too far in depth if I can avoid it.
2) Also, is it recommended to use cookies for this or not? I've heard different views on this?
3) I was told I can set this up in the web.config as well as in code behind? Is this true? If so, which do you recommend?
Thank you very much and I apologize for the broad question(s). If you need any more information, please let me know.
Here is Walkthrough: Creating a Website with Membership and User Logon that you can use.
As far as using cookies is concerned, they can be exploited. To be safe, its best not to put anything of value in them. If you have to, then you should secure them (another topic all together). In the scope of your question, know that ASP.NET encodes and hashes its authorization ticket so you are ok using the default cookie settings. More info on the Web.config form element attributes here.
Forms Authentication is setup in the Web.config file. You can set the slidingExpiration attribute to log a user out if they haven't made a request with in the time set in the attribute.
Take a look at this MSDN tutorial:
http://msdn.microsoft.com/en-us/library/ie/xdt4thhy.aspx
You can use the builtin asp.net sql membershiprovider and login controls for register and login this is implemented in the default web application project.
Then you can check the value of Request.IsAuthenticated in page load and redirect to login page with Response.Redirect(loginPageUrl)
1) http://www.asp.net/web-forms/overview/security good place to start.
2) If you are using the ASP.NET builtin authentication in most scenarios you dont have to worry about cookies. IMO nothing wrong with cookies :)
3) Usually you have to set this up in both. Generally you configure the auth method and the providers in web.config and do the redirection to login page in the codebehind or globally in global.asax.cs
Hope this helps.
Check How to: Implement Simple Forms Authentication.
This type of authentication requires a log-in form referenced in web.config. It can be done with or without cookie: Cookieless Forms Authentication.

Categories