Request activation via HTTP GET - asp.net

In my ASP.Net MVC website, whenever a user registers, the admin should activate his/her account. In my view, I'm creating simple links for this:
#Html.ActionLink("activate", "user", new { id = item.ID })"
I usually would create a form with a #Html.AntiForgeryToken() and POST it to the controller. However, I think it might be OK to do this via HTTP GET since we're doing this for users which are in admin role. Should I use the POST method or is it OK to continue with the HTTP GET and just an id field?

I think it might be OK to do this via HTTP GET since we're doing this for users which are in admin role.
Nope. If anyone sends the link to /user/activate/42 to your admin and he clicks it, he just activated a user.
Apart from the security, read When should I use GET or POST method? What's the difference between them? for the implications on HTTP level, which also regards browser implementations (caching, warning for re-post, and the list goes on).

A GET request should never change the state of the system. It should leave the system unchanged. You don't want anyone to be able to approve users by making a GET request as it leaves the system open to attack. A GET request should also never be used to pass data around.
You should use a PUT request for this ideally. If you can't use a PUT then a POST is ok.

Related

Informing caller additional setup required before continuing

Need help to understand standard flow for handling additional-information-required scenario.
Context: We have a number of product implementations, all integrated with a central single sign-on server. A registered customer can opt to start using new products on-demand. But some of the products require the customer to carry out some one-off setup steps before they use the product - these steps are only needed the very first time of using the product.
Consider a customer is on the page https://product-abc.ourdomain.com. And now clicks on a link within that product something like 'do something (note, this will redirect you to product-xyz)'. At this point the customer is redirected to https://product-xyz.ourdomain.com. Here we want to detect whether the customer is using the product for the first time and if yes, redirect the user to a setup page wherein we can prompt them to supply the product-specific additional information. On the other hand, if the customer is already configured for the product, they will just navigate into the product page and continue using it.
I wanted to know if there is something similar to the 401 Unauthorized flow to handle this. With authentication flow,
A client tries accessing a protected resource.
The server checks the caller has requisite authentication and if not, returns 401 Unauthorized status code with additional details in the WWW-Authenticate header.
The client carries out authentication - say by integrating with the central single sign-on server - and then reattempts the original request, this time succeeding.
I'm wondering if there is a similar flow like,
A client tries accessing a protected resource.
The server checks whether the client is OK to use it. In our case, if its the first time a customer is accessing the product, this check will determine additional setup is required. For example, the client has to supply us with their correspondence address so that we can set up a data tenancy for the specific customer. Here I would like to return a HTTP status code, say, 4xx Setup Required with additional information in a header, say, WWW-SetupInfo.
Once the initial-setup flow is completed, the customer will be redirected to the main product and carry on using it.
The nearest status code that seems to match my usecase is 402 Payment Required, but product-xyz doesn't need any specific subscription or payment. We just need some product-specific additional information to do the initial configuration.
I can handle it by doing custom implementation using 3xx redirect but I was wondering if there is a better way of handling it.
Thanks for any pointers.
Unless you are using basic-authentication, you don't want to use a 401 Unauthorized" status code with a WWW-Authenticate` header. This built in mechanism in browsers has very limited functionality:
Always prompts for user name and password, with no mechanism to customize the process either with look and feel, or custom workflows. You say you want to use single-sign-on. 401 Unauthorized is not compatible with that.
Has no log-out mechanism
Has no session timeout mechanism
As a result, almost all websites use logins based on forms and cookies. If somebody isn't logged in, you should use a 302 Temporary redirect to the login page.
Similarly, if somebody doesn't have their initial setup completed to use a particular page, you would not use a special HTTP status. You would either present them with the a 200 OK page with the form asking for the data you need, or use a 302 Temporary redirect to take them to that form on another URL.

Posting Notes on Gitlab API as a 'bot' user

I am developing an application that posts comments into Merge Requests on Gitlab. It works by authenticating with a given user, and then after some setup will register a webhook on the relevant project to be informed when a Merge Request update happens. When a new Merge Request is detected I want to post a comment on the Merge Request asking for some specific detail to be sent over.
However, when we post the comment on the Merge Request we can only ever seem to do it as the user that we have the OAuth token for (which of course makes sense). My question is what should we do/could we have done in order to post the note as a 'bot user' without having to register a full user into the repository? Or is this just impossible?
You can create a reporter user and use its access token. The problem my arise when the user doesn't have enough access control.
You can create a project scoped token, a bot user will automatically be created for such a token
Ref: https://docs.gitlab.com/ee/user/project/settings/project_access_tokens.html

How to know if user is authenticated on the first request with firebase

Given a backend wrote in nodejs that returns a page that should either link to login (if the user is not logged in) or a link to logout (if the users is already logged in).
Considering I'm using firebase as authentication tool, how can I know in the first request, when the user is accessing the website, if is he authenticated to then
set the ejs template to respond with the correct link ?
Is there some header, or token that can I use ?
The only solution I found was use ajax after the server response, but I don't like this solution because apparently there is a delay in the link renderization.
As far as I know there is no way to know if the user is authentication on the initial request. From a quick inspection no data is sent along with that request. That kinda makes sense, given that upon this request it is not even known if you're using authentication to being with.
Update
I actually just ran into this blog post from one of the Firebase engineers, which seems promising: Introducing session cookies for server-side web apps. I haven't fully read it yet, but the title sounds like it may be exactly what you want.

Java EE: Unauthenticated POST and j_security_check

I tried to do some research on this and came across the following question on another site:
http://www.theserverside.com/discussions/thread.tss?thread_id=36561
Unfortunately, the answer there was to switch to GET requests, which I'm hoping there's a better solution. To reiterate the problem:
The scenario is when a user is on a search page for instance, their session expires, and then they click the submit button. At this point, the login page shows up since they aren't logged in anymore. After successfully logging in, j_security_check is resending the POST request to the search from before but without any of the POST data. I would like to be able to get the POST data from the original request, or I want to configure j_security_check to never send POST requests after logging in, but instead force it to use GET requests.
Any help is greatly appreciated.
I ended up checking in the doPost method to see if request.getParameterMap().isEmpty(). If it is empty, then j_security_check sent the POST request since it doesn't send any POST data. If that is the case, I just call the doGet method instead.

Persisting data cross domains?

I have 2 applications, each in different domains. When a user comes to the first application, clicks a link, the user is sent to the second application.
My problem is as follows: I need to persist a sessionId from the first application to the second application. Simple enough but here's the catch. I can't use query string and I can't use cookies(since in different domains). I was thinking, is there a way to insert custom values into HTTP Headers or set some form values on an intermediate page which would then POST to the second application? So the process would be as follows:
User clicks a link on the first page, this takes the user to an "intermediate" page, this "intermediate" page sets a sessionId value in the form or http Header, then the "intermediate" page sends the user to the second application via a POST where the app will have the sessionId.
I can't use a Server.Transfer since the app is not on the same server. Help?
This is how Microfot tried to do it Does Issuing Passports Make Microsoft a Country?.
You could try and make a secure SOAP or XML request with a secure token referencing a session id you stored for the user in a shared database. You could then load the user's session based on that session id stored in the db if a match is found.
One way that you could do it is to use webservices. Before the user is to switch sites, you could give the user an unique authentication token that has been agreed upon prior to leaving.
Another thing you could do (this is not a great solution, but it works) is to use frames, and to send the child frame information through javascript (login information). I really don't like this method, because it presents so many problems that its best avoided.
What I mean:
Web services: Communicate with the other site to say "this user is currently logged in here," you can do this at login (depends how much you trust the other domain), or you can do it when the user requests to leave
Giving the user an authentication token: You can post it as a form element. Or if you had an agreement with both domains you could send it to a URL that could later be interpreted as a rediection service+authentication token confirmation portion. I.E.: domain.com/page/token+pageid-mixture
Use OpenID. It's designed for this purpose (common authentication to web sites on multiple domains). The protocol's been under development for years and has probably encountered and solved a lot of the problems you'd be likely to run into if you roll your own solution.

Resources