We have a React application protected by a separate Identity Server site. When unauthenticated, the user is redirected to the login page within Identity Server and then on successful login they are then redirected to a callback URL within the React application.
I'm trying to automate this process as much as possible to improve the speed and reliability of our Cypress.io tests so that we don't need to login via the UI each time - allowing the tests to be atomic and free of unnecessary complexity.
What would be the best way to achieve this?
I've followed the examples the Cypress team give around logging in, but haven't been able to get it close to optimal:
https://github.com/cypress-io/cypress-example-recipes/tree/master/examples/logging-in__single-sign-on
The closest I've come so far is by following this Auth0 article, but fell short of populating the id_token, nonce and state values to pass to the callback URL:
https://auth0.com/blog/end-to-end-testing-with-cypress-and-auth0/
Any direction greatly appreciated.
I was able to get around this by hitting the /connect/token endpoint of the Identity Server:
POST /connect/token
client_id=client1&
client_secret=secret&
grant_type=password&
username=username&
password=password&
scope=openid profile <client_scope>
And then used the response to add an item into session storage:
window.sessionStorage.setItem("oidc:<auth_url>:<client_id>", JSON.stringify(response));
Related
I am trying to make a secure way to proove that a user is logged in within my react app.
Currently when the user loggs in i save his user id to the local storage. After a while i found out that this isn't save enough because you just can open dev tools and eddit the values of the localstorage. So how can i do this so that you can't type in someones user id and be logged in as the selected user? I googled this and found out that you can use cookies. I am also planing to do this but i also looked at the devtools and saw that it is also possible to edit them. So i think i need to change something in my code maybe an extra token or an encoded user id or something. But i realy dont have a clue on how to deal with this so that it is realy secure? Hope someone at least could point me in the right direction. Thanks a lot for every answer.
That is so true saving a token for example JWT in local storage or cookies this is not a safe way of handling user sessions. Because with JavaScript one can interact with the local storage of cookie(if they are not httpOnly cookies).
What is the best way of handling user sessions then?
The solution that you would want to explore is server side session cookies
So server side session cookies will be made from your dedicated server and have it set the cookie in your browser and flag it as httpOnly.
So by this said no script written can interact with that cookie cause it is an httpOnly cookie
If you are using both React and Node:
If your using the two I would advise that you look into Express-sessions
I'm building an admin page for an application and have a state value 'authenticated' that flips from 'false' to 'true' after a successful login (which is authenticated on the server) which then shows the actual admin panel.
Are component state values safe from tampering by the client? Basically, if the client can modify my 'authenticated' state value to 'true', they can skip the login and go straight to the admin panel (which I obviously don't want).
I read that React Dev Tools allows the client to modify values yet everyone says "validate on the server" but I am validating on the server and updating my state accordingly, if the user is approved. If it is not wise to have a state value manage this, what is the right way to conditionally show the admin page after a successful, server-side authenticated login?
I think this is an important question since tampering with state values in a React app can have huge negative consequences on data integrity within an app/database.
TL;DR: Either require an authentication token with every request or require authentication through a session.
Never trust users always. One potentially big issue is if you "hide" admin actions behind the admins page without requiring authentication.
For example, assume the backend server uses a REST API to accept commands. In the admin panel you get links to administrative actions like a button 'Delete Everything' that sends a DELETE request to server.net:8080/api/admin/everything without requiring any authentication. If you're a user, you can find that in the code potentially and then send a DELETE request to that address from anywhere without any repercussions.
We'd never give administrative privileges to anyone who would want to delete everything... Because we'll never untrust someone. Right?
Worse, someone might find the server and fuzz some inputs to it, and oops! They manage to delete everything (or even worse, GET everything stored in the database). This wouldn't be hard to do, especially if the server you use to authenticate is the same server you use to issue commands. History has proven "security through obscurity" to be a very bad paradigm. Every action should be authenticated, even if it seems like the actions will be hard to find.
Generally, providing a JSON web token or some other form of authentication token and having the user send that with every request is a good start at least, especially if it has an expiration date. The token would be provided through a separate request with valid credentials.
Sending a token with every single request obviously isn't ideal. There are a couple of other things to try. For servers using PHP, you can probably trust sessions (though very many people who know more than me would probably disagree). In more modern cases, you could try to use Web Sockets, requiring the token after connection. Then only after authentication with the token do you allow the user to make administrative requests.
That way, even if a user knows the exact command they can send to perform any action, the server won't let them without a current session or token. Unfortunately, unless you're already using Web Sockets or depending on a session, it will likely require a lot of changes. I'd consider this to be critical though.
It is always possible to tamper values in the front-end, there is no way you can rely solely on the front end to ensure security.
Your best approach is to implement some form of authentication and authorization on your backend. In this way, even is some users pretend to be admin, they will be blocked when you do the next request to the server.
Perhaps if you can send more information regarding your problem, we can think of a more specific solution.
I am developing an application where users are playing a game and upon completion their results are sent to my back end through a POST request. Since I do not want this POST request to be done manually by someone who finds this endpoint (and mess with his results), I need a way to restrict it so that it can be done only through the application. However is it safe to hardcode a token that provides this access?
What is the correct way to go around this problem ?
I would not recommend to use hard-coded tokens, if the token gets compromized, you have to change the server as well as the client.
I would recommend some sort of auth mechanism as JWT with ssl with one rudimentary username/password system.
I am creating an Angular application, and I am having trouble wrapping my head around the proper way to ensure my application and its users is secure.
I've been reading around many stack discussions, but I believe I am missing some core understanding of what is happening, please correct any errors you see written below.
So far I have a Sinatra server with many (currently mostly hypothetical) resource routes. A user can create an account using an email address and password that is stored in a database after being hashed with BCrypt. When a user logs in, the record is retrieved from the database by email and the password checked for authentication. It is from this point I am not sure how to proceed.
Prior to this I have simply set a session variable and had the server check that the variable exists in order to correctly route logged in users. Now my application is (currently) a single HTML page that uses Angular and ui-router to display different content, so most of the requests are simply returning JSON content.
It is my understanding that Restful applications should generally not use sessions, or rather that the server should respond identically to identical requests and not have its own data that shapes a response. But if I do not store something in a session variable, how could the server know that the client making the request has the correct permissions? And are sessions not stored in the browser anyway, thus not part of the server?
I believe from what I have read, it is possible to create a token which is essentially a large random string, return that string to the client and also store it in a database with a timestamp. The client then provides this token when making requests and the server hits the database to verify it exists and valid. But would the client not also have to store that string in a cookie? I suppose the angular application could store the token in a variable, which would persist while using the ui-router but not if the users navigates using the address bar.
I also do not understand how Basic Auth may or may not fit into this picture. Any help would be greatly appreciated, as well as a pointer to some good resources where I may find a better understanding of these concepts in general.
You want to read up on JWT. There are JWT libraries for Ruby and Angular.
I know you aren't using Node for your backend but a very easy way to see all the pieces working together is to run the angular-fullstack Yeoman generator. It uses JWT and the code is easy to follow.
As far as I can see, whatever you are doing with your sessions can work just fine.
This can be a sample JSON response from the server in case the user is not loged in :
{
"errorCode": 1,
"error": "User not logged in",
"data": {}
}
You can set your own error codes and handle what you want to do. You will send any data only if the user is logged in. For all the pages which don't require authentication, you can set data to whatever you want.
On the angularJS side, you can handle based on error codes, you can redirect the user to the login page and so forth.
The alternate way to support the same on multiple platforms is to use token based approach. The token based approach in simple words work this way.
The user logs in for the first time with his / her credentials.
The server verifies these information and creates a token from which the server is able to decode the user id.
Whenever the client makes the requests, it passes its token with every request.
As the server can decode the user information from the token, it sends or doesn't send the data based on whether that's a right token or not.
The token depends on a secret value. It can be same for all the users or differnet for each based on how you want to implement.
This is all done and you can look at
http://jwt.io/
As #andy-gaskell mentioned, you can look at
http://angular-tips.com/blog/2014/05/json-web-tokens-introduction/
I'm very bad at explaining. Please let me know if any of this doesn't make sense.
you are missing the point of the REST concept. One of the main concepts in the REST apis is that the server should be stateless - this means that you should not store sessions or other "state" in your web server. Every HTTP request happens in complete isolation. Every request should include all data needed by the server to fulfill the request.
But if I do not store something in a session variable, how could the
server know that the client making the request has the correct
permissions?
You can store request scoped variables. This means that they should be only active during the same request. You can store the current logged in user in the request scoped variable. In that way you can get the current user in your invocation of the business method. I'm not familiar with Sinatra but here is the doc: http://www.sinatrarb.com/intro.html#Request/Instance%20Scope
But would the client not also have to store that string in a cookie?
of course you should store your access token in the client side
https://stormpath.com/blog/where-to-store-your-jwts-cookies-vs-html5-web-storage/
as #Andy Gaskell suggest take a look at JWT and fullstack application code generators and forget about the basic auth because it's really "basic".
more useful links:
If REST applications are supposed to be stateless, how do you manage sessions?
http://www.sitepoint.com/php-authorization-jwt-json-web-tokens/
I am working on a wp7 app and I want to make an https call (sign-in and then post ) to a website which does not have an REST API. So I will have to use it just like a browser adding headers to the https sign in call and parsing the resulting data get the Cookie data and unique id assigned extra and pass that on to a subsequent https calls I make.
Can someone please point me to best way to do this ? Pointers to some samples that comes close to this would be helpful.
thanks
If the site in question doesn't prevent CSRF you could just submit form data to it directly. If it does, you're going to need to screen scrape the forms for the website, then populate the necessary fileds and then submit.
If you have control over the site, you'll probably be better off in the long run and be less vulnerable to changes to the site.
If it's not your site, be sure to check permission from the site owner about automating logging in. You also need to be very careful about what you do with regard to the users login credentials.