I have created a simple WebAPI in Visual Studio C# to act as my backend to Angular.
Users can register via the Angular frontend and passed to a controller in the WebAPI to register that user in the backend DB (MSSql). All fine.
I am using token authentication from Angular to my API and using claims and roles to verify the user is logged in and has access to the requested controller.
How, as an Admin, can I disable another user so they are instantly locked out?
An example would be: A rogue user starts abusing the Angular application and I need to lock them down instantly and not to wait until their token expires and they are required to login again.
I could do a check in each and every controller to lookup the user in the DB and check their status and if I have set their status to "locked-out" then return say a 403 forbidden status from the controller but this seems a lot to lookup the user for each DB request they make.
Is there a "dot-net" way of doing it? I would love to be able, as the admin, to instantiate the said user, change their claim value for "status" to "locked-out" and I simply check their claim when making api requests but I can't see a way of changing another users claims.
Any ideas?
Thank you.
Expanding on my comment above, we have a handler in our pipeline that handles Authorization. We do look at that Authorization header and parse it but all of the controllers rely on the already-parsed value that we hang in the Properties collection. That way all AuthZ/AuthN occurs in this handler and whatever the handler sets in the Properties collection is what all of the application sees.
In your case the handler would need to be able to check whatever throttle or lockout you are using and replace the actual claims received with your "user is locked out" claims instead.
Related
I have tried using Hangfire to create a recurring job to run at 3 specific hours daily but i found out later it cannot access httpcontext to signout users, so what i did instead, hangfire task calls a stored procedure at the given hours and I have created a razor pages filter that will signout user depending on a boolean in database that is changed by the task.
I would like to know if is there a way to do this without having to hit the database every http request using the filter. For example,
I would like to log out the user automatically at 6:58am or 14:58pm or 22:58pm
how to achieve this?
You can only sign a user out in the context of a request that specific user is making. The reason for this is simple: authentication is persisted via a cookie on the client. Only through direct interaction with that client (where the client is transmitting the cookie to the server), can you do something about their authenticated state. There is no global store of logins or something that you can simply modify all at once. As a result, you must use the approach of a filter or some piece of middleware in the request pipeline to handle this. There is no other option.
Without creating custom authorization handlers, is there a way in asp.net core to detect the reason that an action fails with a 401 Unauthorized and return a semantically helpful response?
Specific example: User has the role "Student". Action has an attribute specifying [Authorize(Roles = "Teacher")]. When User attempts to load Action, a policy failure results in an error view being redirected to via the authentication middleware.
Ideally I would be able to identify the reason within the error handling action method and provide a specific response stating that the requested URL is only available for Teachers, but so far nothing obvious has presented itself. I can identify which authentication schemes were involved, and which roles the user is in, but it's unclear if I can tell which roles are required for the action.
I have a "chicken egg" problem.
In application I use UserDetailsService to get User (we don't store user information in our DB, we use third party service to actually get all information).
Recently we've added account activation feature. After registration, we send an activation email to a user and if he clicks on it, we mark the User as ACTIVE and redirects him to log in page. User can login only if he has ACTIVE status. The problem is: we'll start charging user from the date he activates his account even if he never logs in. How can I (maybe using spring security) make those processes (activation and login) almost simultaneous? We don't want to charge user if he just activates his account, we want to charge him only if he has logged in (after activation). So can I actually do it somehow "user clicks activation link, login and then his status is changed to ACTIVE (but he can login only if he is ACTIVE)".
Sorry if my problem description isn't clear enough
I'll appreciate any feedback.
Thanks!
If I understood your requirements correctly, you'll need two different entry points (login pages) to your application:
One for activation (first login) for users not yet activated.
Another "normal" one for active users.
The problem is that the authentication logic would need to be context sensitive and be aware of which of the above pages initated the authentication. However the framework was not designed for such uncommon use-cases, so the authentication provider has no knowledge about the URL from which the login-form were actually sent.
What you need to solve is to somehow relay contextual information to an authentication provider that processes the auth request according to that information (i.e. authenticate only non-active users logging in from url1, and authenticate only active users logging in from url2). There could be hundreds of different ways to achieve this, one possible solution is to put two different authenentication filters in place that intercept auth requests sent to the two different urls. Details outlined below:
Create your own custom versions of the existing WebAuthenticationDetailsSource and WebAuthenticationDetails (preferably by subclassing the latter) that stores and exposes the URI of the authentication request. (That will be the contextual information based on which the auth provider can implement its conditional logic.)
Configure and insert two different instances of the UsernamePasswordAuthenticationFilter in the filter chain. Set their filterProcessesUrl attribute to /j_spring_security_check_active_user and /j_spring_security_check_nonactive_user respectively, plus inject the above created custom AuthenticationDetailsSource in both of them.
Override DaoAuthenticationProvider.additionalAuthenticationChecks() in a subclass in the following way:
Retrieve the URI stored in the above created WebAuthenticationDetails object (it's accessible via authentication.getDetails())
Assert that the user is active/non-active according to the URI, and throw an AccountStatusException if the asserion fails.
Don't forget to delegate to the superclass if the assertion succeeds.
Create the two different login pages mentioned at the beginning of the post, making sure that the login forms post credentials to their respective URL (/j_spring_security_check_nonactive_user vs. /j_spring_security_check_active_user).
Has anyone successfully implemented the Google Identity Toolkit, an implementation of an Account Chooser. I followed the initial steps here, but I still have a few questions, as I don't quite know how to handle the entire data flow. I'm using Clojure / Compojure in the back-end:
http://havethunk.wordpress.com/2011/08/10/google-identity-toolkit-asp-net-mvc3/
http://code.google.com/apis/identitytoolkit/v1/acguide.html
A) don't quite understand how ID Provider authentication, fits into my data model
when implementing the callbackURL, what data should I expect, and
how's that session state managed by GITkit (and all Account Choosers)
B) Is there a way to set this up the 'callbackURL' for development.
the identity provider would need a URL that it can redirect back to
C) How can the GITkit / Account Chooser workflow let my users register an account that's native to my app?
Thanks in advance
The questions aren't entirely clear, but I've done an implementation of GITkit in ruby and can give you some pointers.
A) The callback URL is what handles the assertion from the identity providers. Rightnow GITKit only does OpenID, so the URL will contain an OpenID response either in the query parameters or as the POST body. You'll need to do a few things:
1) Call verifyAssertion in the gitkit API and pass the params/post body. This will return a JSON response that contains the user details (assuming assertion is valid). There are some other checks you should do as well
2) Decide what to do with the assertion. If it is an existing user, most likely you'll just establish a session and save the user ID. If it's a new user, you can either create a new account and start a session immediately, or defer that and redirect them to a signup page.
3) Render HTML/JS to notify the widget. There are different status codes and data you can return that changes the flow.
GITKit itself doesn't really manage session state, that's up to your app. Some of the reference implementations have code to help, but it's not part of the API. The widget does have some state that you can control with JS (add account, show as logged in, etc) and uses local storage in the browser.
The docs give some details and example code for how this should be implemented.
B) Of course. The URL is just configured in the javascript widget when you call setConfig() It can be set to localhost or any staging server for development. So long as your browser can reach it you're OK.
C) By "native", I assume you mean where they're signing up with just a username/password instead of using an IDP. If so, the user just has to enter their email address when logging in. If that email address matches a known IDP it'll attempt to authenticate with OpenID, otherwise if it's a new user it'll redirect to whatever signup page you configured in the widget. That signup page would just ask the user to create a password like you normally would. You should also return whether or not accounts are 'legacy' (password) accounts in the userStatus checks.
Hope that helps.
For anyone's future reference. I was able to resolve the issue. You can follow this thread of how's it's done in Clojure.
I got it working with Ring/Compojure, and another fellow showed me his solution in Webnoir.
HTH
My application has some features that are accessible to all users, and some other features to which access should be restricted to authenticated users only. All these restricted features exists within some set of GWT Places, thus, all Places available in application can be divided into two groups: "accessible for all", and "restricted". In my opinion, places with restricted access, could implement some interface (let's say it would be RestrictedAccess), and if user proceeds to one of them, and it has not been authenticated yet, it will be redirected to the login screen - it's more OO-approach than applying filters basis on URL.
What I'm trying to achieve is:
Information about if user has been
authenticated or not should be
stored on server (it's not something
that could be stored in a cookie...)
Login page is a standard GWT place+view+activity (!)
User name & password validation is done on the server side.
So far, I've introduced RestrictedAccess interface, which is implemented by some set of places. My FilteredActivityMapper.Filter implementation, which is passed to the FilteredActivityMapper wrapping application activity mapper has the following logic:
Place filter(Place place) {
if (place instanceof RestrictedAccess && !userHasBeenAuthenticated()) {
return new LoginPlace();
}
// return the original place - user has been already authenticated or
// place is accesible for all users
return place;
}
private boolean userHasBeenAuthenticated() {
// remote call - how to do ???
}
The problem is with userHasBeenAuthenticated() method (user should not be redirected to the LoginPlace, if it has been already authenticated). If I want to store this information on the server-side, I have to do GWT RPC/request factory call here, but both are asynchronous, so I cannot work on its result in the filter method.
I know that I can use web.xml filters or some external framework (e.g. spring security), but none of this approach allows me to have login page as a standard GWT - based form, or indicating in the more OO way that access to some place should be restricted.
Thanks in advance for any hints
EDIT: I've started to wondering if places filtering (restricted/not restricted) should take place on the client side at all. If, as it was suggested, there is a possibility to hack code indicating if user has been authenticated or not, there is also possibility to hack places filtering code, so that it will be possible to access restricted places without signing in.
Piotrek,
I think there is a security issue with calling userHasBeenAuthenticated() - it would be possible to hack the client side code to return true every time this function is called.
The solution I've implemented is to simply return SC_UNAUTHORIZED if an unauthenticated user attempts to access any remote service. I've overridden the RequestFactory onResponseReceived function which redirects to a login page if the response is SC_UNAUTHORIZED. Idea taken from:
http://code.google.com/p/google-web-toolkit/source/browse/trunk/samples/expenses/src/main/java/com/google/gwt/sample/gaerequest/client/GaeAuthRequestTransport.java
This works for our situation where the Activities and Places are all data-centric - each place change retrieves data from the server. If a user isn't authenticated they simply don't get the data and get redirected to a login page.
I realize your situation is slightly different in that some places are accessible to everyone, in which case you could configure only the restricted services to return SC_UNAUTHORIZED.
I have a similar application with the same requirements. As yet I have not got round to to the implementation but I was thinking along the same lines.
What I was planning on doing is storing the authentication state client side in an AuthenticationManager class. When the app starts I was going to request the login info from the server (I was thinking of running on app engine so I would get the authentication state and also get the open id login/logout URLs) and store this in the AuthenticationManager. Acegi/Spring Security works in a simlar way so this info is available server side if you use those too.
When the user logs in/out they will be redirected by the server and the new state will be retrieved. This should keep the client authentication state in line with the server. Each RPC request on the server has to be checked for authentication too. I was using the gwt-dispacth library and this has some rudimentary authentication checking and cross site script protection in in too (although I think latest GWT has this for generic RPC).
One issue is session timeouts. Again the gwt-dispath library has some code that detects this and returns session expired exceptions to the client which can be intercepted and the auth manager updated.
Hope that makes some sense.