I am assigned with the task of performing authorization in asp.net webforms. So I need to check if user is allowed to visit the page. So started like I stored users privileges in Db and upon login I fetch privileges also.
What is now done is in every page load I check if the page name is in privilege list. then I come across terms like handlers,modules,global.asax which are targets where I could write all these tasks.
Is this the right approach?
What should I choose> Gloabasl.asax or handler or module
you can create a class inherits from page class, and add your method there. then make all your pages inherits from the new class
Related
Using Identity Serve 4 with .Net Core 3.1, razor pages. Also using Cookie Authentication
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
Problem -
In a web application John logged-in 2 times
1st Login on Chrome
2nd Login on edge
So, if John again trying to logged-in on 3rd time on Firefox without logout from previous browsers, then I want to logout John from 1st Login on Chrome forcefully.
I can keep the track of logins in a Session table including Session Id, User Id etc.
But I don’t know how logout user from a particular session using Session Id.
Please help.
Thanks
ASP.NET Core provides an ITicketStore interface which allows you to get control of storing user sessions. Once you provide a class implementing this interface and register it, it will call your class when sessions are being created or verified which you can then store in a database however you like, including attaching arbitrary metadata like browser ID etc.
Now that you have user sessions in your database, you can separately query them and revoke as needed in other logic, including during logins. Since you now provide the session data, simply deleting the record effectively logs the user out from that session. Note that if you use any caching layer to reduce the store requests, you'd need to remove any cached copies as well.
Note that this is separate from IdentityServer and happens with ASP.NET Core itself.
This is a good tutorial that helped me implementing this in my app.
A sample of how it looks to register in Startup, where PersistentTicketStore is my implementation:
// Persistent ticket/cookie store to provide durable user sessions
services.AddSingleton<IUserSessionRepository, UserSessionRepository>();
services.AddSingleton<ITicketStore, PersistentTicketStore>();
services.AddOptions<CookieAuthenticationOptions>(CookieAuthenticationDefaults.AuthenticationScheme)
.Configure<ITicketStore>((options, store) => options.SessionStore = store);
Use the End Session Endpoint
The end session endpoint can be used to end a session and trigger a log out
In the log in process you will need to capture the id_token received from authentication and what user it belongs and store it on some dbo.table. You can use this same table to also keep track if a user has logged in more than once.
To log out a user or end a session you will need to pass the ID you saved as a query string parameter called id_token_hint in a GET call as shown below into:
GET /connect/endsession?id_token_hint={id_token}
For reference see the documentation here https://identityserver4.readthedocs.io/en/latest/endpoints/endsession.html#end-session-endpoint
Since you're saying you can keep track of logins, perhaps you should keep track of each session and assign a number somewhere indicating when it was logged in (1 for Chrome, 2 for edge, 3 for Firefox).
Then each time a request is made, you check in your table what the lowest number is (1,2,3 etc), and if the session matches that number, you sign the user out from that session.
await
HttpContext.SignOutAsync(IdentityServerConstants.DefaultCookieAuthenticationScheme);
Since each browser will have their own cookie, you can use the above method.
After signing someone out, the next login can be assigned 4, and if 2 makes a request you log that client out.....
Also see this: https://github.com/IdentityServer/IdentityServer4/issues/736
I have implemented this.
When a user logs in, the session id (IUserSession.GetSessionIdAsync) is manually stored in our database. The previous value of this database field is used to create a logout_token which I send to my clients. You can have look at IdentityServer4.Infrastructure.BackChannelLogoutClient to figure out how to create the token and post.
All this assumes you have backchannel logout implemented ofcourse.
In my application I plan to use SignalR in order for the backend code to send messages to the logged in user based on the conditions that arise on the server.
In particular I want the SignalR to call methods on the JS client whenever something happens on the backend. This could be periodic calculations happening on the backend that suddenly pass a threshold and I need to invoke something on the JS client for a particular User. The particular User is the key element here. Only the User that should know about this.
I'm assuming this should be very simple with SignalR but I have some problem understanding the way to implement this. My solution is as follow;
Each time a user logs in, I create a SignalR Group and add that user to that group.
Each time a user logs out, I remove them from the Group. (I don't know if I can also delete the Group itself)
Now each time something happens on the back end, I use SignalR to push information to a particular User that needs to know about that event by calling a JS client method and sending to the group with the name equal to the Name Identifier of the user of interest.
So to apply this solution, I need to get the information about the User that just logged in inside the C# Hub in order to create the group and join him.
Now my problem is, how to access the information that I need from the User that logs in to the application in the C# Hub . I'm interested in the User Name Identifier of course. I have been thinking that the Context Property in the Hub should give me the information that I need (This is my understanding of the MS Docs) but I cannot make it to work. Please study below code.
// As soon as a User logs in, below method fires. I try to get the information
// in here but no success
public override async Task OnConnectedAsync()
{
var CID = Context.ConnectionId; // this gives a unique connection ID
var user = Context.User; // This returns nothing
var userID = Context.UserIdentifier; // This returns nothing
var httpContextObject = Context.GetHttpContext(); // This returns nothing
await base.OnConnectedAsync();
}
When I call other methods in the C# Hub from JS the method is fired and
information is passed but I still have no access to the information the
Context Property should provide.
Please help me first by confirming or correcting my overall approach and if there are well known best practices available. Secondly please let me know how can I get information that the Context Property provides in the Hub and generally where this information is available and how to access and use them.
Many thanks in advance.
'User' is a claims principle (normally stored in the asp cookie), to get the User form your Identity database use:
var user = await _userManager.GetUserAsync(User);
For future reference, your question is very long, you will get more help if you keep questions brief and to the point.
I've solved my problem by using Authentication with SignalR. I don't need to add a user to any groups to push massages to them. In the Startup class I add Authentication above SignalR service and then the user object is passed to the Hub in the Context property. I can also push to any user by injecting the IHubContext to any class constructor I need.
I am setting up a new mvc5 project in c# in which I am using Identity Framework and Open ID. which means a new user can register via a third party i.e. Google,Facebook,Microsoft.
So this part is done. Now I want to restrict users, means when a user will be trying to register an approval will be sent to the Admin. If the Admin accepts only then the user can register. Is there any way to do that?
Check out a combination of Authorization Policies/ Role Based Security. When any user registers via a third party, the code which handles the registration does all the relevant record keeping for the new user, and gives them a role of, say, "Unapproved User". You can create as set of Controllers/ Views etc which that user can view (perhaps a profile page, landing page with generic information, or maybe just a disclaimer page which tells them they need to wait to be approved).
From there when the Admin approves the user, the code which handles the approval changes the role to "Approved User". This then allows them to access the full site.
I can't tell if you are using classic Asp.Net with mvc 5 or Asp.Net core but the concepts are similar (except for the auth policy stuff) in both.
Essentially you decorate the controllers/ actions you want protected with:
[Authorize("ApprovedUser")]
public class MyProtectedController
{
}
[Authorize("UnapprovedUser")]
public class MyUnprotectedController
{
}
For more info:
https://learn.microsoft.com/en-us/aspnet/core/security/authorization/roles?view=aspnetcore-2.2
In my ASP.NET web application and there is one function will consume a lot server resources.
When running this function, i would like to temporary disallowed user to access to certain page and redirect user to a alert page to inform them come back later.
When this function is completed, users will allowed to access all pages.
Is there any way i can do this?
In the page you do not won't to get user access simply write this line of code under page_Load
Response.Redirect("Thealertpage.aspx");
Then in your alert page place your message to the users and a button to redirect somewhere else in your website using the same line above but with a different page link. Alternatively, just remove the page and name the warning page as per the removed page.
I was also considering to suggest you to use a session variable to be set in your admin page by a check box but you would need to save the checkbox status in the db. Too over designed for something temporary like in your case.
I have a ASP.NET MVC site with a CAS server set up as the authentication type. I also have a separate database with a Users table and a Roles table (with a User being related to one or more roles). A User is only able to log into the system if the Username is both in the User table and on the CAS system. I have this solution working.
My problem is i now need some form of trigger on User.IsAuthenticated so i can track the current User (from my database), without the possibility that i am trying to allow tracking of a User that has logged out. What I've been thinking is i need to add the User to the HttpContext but i am not sure how to trigger the clearing of the User if the CAS session times out or if the User Logs out.
I also wish to have some functionality such as User.IsInRole (again using my database, not ASP.NET) but am not sure how to go about implementing this. I suppose if i can successfully add the User to the HttpContext then a IsInRole method would simply be a User.Roles.Contains(string role) method but how can that then be used if i wish, for example, to use a method with the DataAnnotation [Authorize(role = "ExampleRole")].
I have looked at questions such as How do I create a custom membership provider for ASP.NET MVC 2? but this doesn't work for me (possibly to do with me using the CAS authentication?)
Any guidance or background reading would be appreciated as i'm really not sure where i should even start. I have read up on GenericPrinciple, IPrinciple and IIdentity but I'm struggling to see how i can apply them to my current project.
Ended up with a custom Authorise Attribute that uses the CAS logon to check the user exists in my database. It also checks the roles of that user. I also used a static class to save the current user in the session with a logout method that abandons the session when the user logs out.
I have kind of a two parter for you. This link does a really good job of explaining how to replace the HttpContext User with your own object: http://bradygaster.com/custom-authentication-with-mvc-3.0
His approach uses MVC filters, but you can also catch the Authentication event in the Global.asax file. Using the forms system with your own implementation can be trivial or not depending on what you're doing, but it boils down to calling FormsAuthentication.SetAuthCookie and .SignOut, amidst your own logic.
public static void FormsLogin(this User user, bool persist)
{
FormsAuthentication.SetAuthCookie(user.DisplayName, persist);
user.AddHistory("Login event.", HistoryType.Login, "SYSTEM");
Users.OnUserLogin(user);
SetLastActivity(user);
}
public static void FormsLogout(this User user)
{
FormsAuthentication.SignOut();
}
Lastly, once you've got the login stuff working out, you can use your own more complex permission system by making a custom Auth Attribute. I remember piecing this together from some other answers and articles but I can't seem to find the sources at the moment, I will try and edit with sources for credit where it's due, if I find them. For now, all I can offer is this gist which offers up one of the attributes I use: https://gist.github.com/1959509
Keep in mind the only really relevant part there is the override of OnAuthorization, which does the actual work.