Is it nessesarry to send credentials on every single request to MVC Web Api? - authentication

I am about to create my first restfull web service where i chose MVC WEB API to be the "provider". After reading about authentication i am a little confused.
My requirements is that on call to any url of webservice i want client to be authenticated, except sign in url.
I understand the flow this way: after client is signed, webservice returns a authenticationtoken which client have to store, and send to the server on every request in the headers. But where is this token stored on the webservice?
I am very confused at which flow of actions i have to implement if i want to avoid users to pass login parameters on every single request.

Typically how this works is that the user's authentication token will be stored in a cookie. Once you authenticate the user, you will create a 'session' for them server side. There will be a 'session token' that corresponds with this session.
When the user signs in, you will create a new session for them. This will send them a new cookie. Every future request they make will contain this cookie. You will then use this cookie to identify the user's session. From it, you can draw their username, etc.
It sounds like what you really want is the .net State management (https://msdn.microsoft.com/en-us/library/75x4ha6s(v=vs.140).aspx). You should look into using this, and see how you can apply it to your current needs.
In the long run, once you've got proper user session tokens, you will not need to send their credentials with every request. The session token will be good enough to identity the user upon every request that they make.

Related

Persisting a login with the Slack API

I currently have this flow but I am unsure of the architecture going forward.
On my page, the user gets sent to the Slack OAuth API where they confirm scopes
User gets redirected back to my page with a one time code
Client sends a request to the server with the code
The server sends a request to Slack with the code, exchanging it for an access token
If the code and token are OK, it creates a new user in MongoDB
I made a flowchart to illustrate:
I would like the user to not have to authorize the scopes every time they want to access the service, and even if they did, how would I keep the token around in a secure manner to make requests? Would I have to create my own token authentication with login and password, or is there a better way? Should I persist this token on the client somehow and have the users be logged in that way? If so, what is the best way to do that?
Slack token generation must be one time activity per user.
When creating user in MongoDB, you should also store the generated token securely.
For later use, your application should use the stored token for any slack interactions, given that you have authenticated the user whose token you'll be using.

is JWT better than Session?

I wrote an API that uses JWT to authenticate the incoming requests.
I connected an ASP.NET Core application to this API. When the users login to the application, it asks the api if the credentials are goods, and if they are the api sends back a JWT token to the application.
This application finally stores the JWT to an httpOnly cookie on the client.
Now, I want to use the "User.IsAuthenticated" feature to displays the name of the actual user if he possesses a JWT cookie.
To do so, I wrote a JWTManager which analyze each requests of the application and if the user possesses a JWT cookie, the Manager will authenticates the user with HttpContext.SignInAsync by decoding the JWT, verifying his authenticity from the api then reading all the claims it contains before adding it to the User Session.
Tldr, I discuss to the api with jwt but I use cookie sessions on the application, sessions that I ironically create from jwt too.
My question is, do I need to keep sessions ?
Basically, I implemented the cookie session to use the [Authorize] annotation. But because the api already uses it, I can simply verify if the api returns unauthorized to stop the user from accessing the content he isn't authorized to use.
To display the name, I can avoid the User.Identity.IsAuthenticated and simply look for his JWT, verify if its authentic from the api then displays his name from the JWT. If he hasn't a JWT, I can display "Sign in" instead of his name.
What is the optimal way to use JWT ?
I choose it to reduce the calls to database from the api and to make the cross applications easier to use. And avoiding session will also reduce the memory used by the server to store them.
But is it worth it ? I'll ask the api if the JWT is authentic at each request from the client, then decode the JWT to at least write the username on the navigation bar to each requests (yes I can use cache and ajax to avoid reloading the navbar at each request, but I still need to verify if the user has access to the content).
Is it more efficient than just use a session with several roles and [Authorize] my content ?
Or finally my mixed use of both feature is efficient ? (Authenticate and discuss with the api from jwt will using session on the application)

Can't modify user private data with Client Credential Flow by Spotify Web API

Is there any method to modify i.e. playlist by Web API by with console based application in Client Credential Flow ?
https://developer.spotify.com/web-api/authorization-guide/#client-credentials-flow
Propably not, but maybe I am wrong ? I want to modify only my user's data.
Here I created issue at API specification
https://github.com/spotify/web-api/issues/165
One of the benefits with the Client Credentials oAuth 2.0 flow is that applications can make authenticated requests to a web service without a need to involve an end user. Since a user isn't involved, the requests that can be made from the application is limited. For example, using Spotify's API, you can still make requests to retrieve track metadata, playlist contents, and search for albums. Any endpoint that requires a scope can't be used since it requires user interaction.
So using Client Credentials simply doesn't make sense if you're interested in making requests on behalf of a user, or if you want to access private data since the user needs to give you permission first.
You need to use Implicit Grant or Authentication Code Flow for this. I advise that you read further about the supported oAuth 2.0 flows in the Authorization Guide. One of the benefits of using the Authorization Code flow is that you'll also retrieve a new refresh token, which you can use to retrieve access tokens indefinitely. It however requires you to write a web service that accepts an authorization code and exchanges it for the tokens. The Implicit Grant flow doesn't return a refresh token, so it's only possible to use for one hour until the access token has expired.

Client cookie for token in API environment

The backend for my client web application is a JSON Api. I wanted to keep the backend generic so other devices such as mobile could reuse the same service.
Let's say each user account has a token in their profile, when they login with their username/password I send the token back. In each subsequent request I send back the token, look it up in the database in order to find out who the user is.
As the user moves throughout the app, how/where do I store this token. Do I store it in a cookie? Do I drop an additional cookie in order to keep some kind of session state going?
First of all this is not 100% RestFul.I have faced a similar situation. blogged it here
The solution is, I created a singleton object to store user authentication token in the application container.Then a filter was configured to query the request and get the authentication token sent by the client. Then this token is matched against the token stored in the Singleton Session object.

Password protecting a REST service?

After creating a basic REST service, I've have come to the point where it would be appropriate to add some sort of password protection, as I need to verify that my users are both properly logged and have sufficient permissions to execute whatever action they are going to.
The REST service will mainly be accessed from a Javascript-heavy frontend and with that in mind, I have come up with the two following alternatives to solve this:
Make users login by first sending credentials to a /login page with POST. The page sets a session cookie wherein the user is
marked as logged in, along with the permission level. On each
following request, I verify that the user is logged in and his/her
permission level. When the session expires, automatically or
manually (logout, the user will have to re-logon).
Temporarily save the credentials hashed locally and send the users credentials along every single request made by the user to verify the credentials & permissions backend on a per-request basis.
Are there more ways to solve this and is there something else that I should be concerned with?
I'm currently developing a REST API along with a client (written in javascript), below I'll try to explain the methods used to protect the API against unauthorized access.
Make your REST API to require a Auth-Key header upon every request to the API, besides /api/authenticate.
/api/authenticate will take a username and a password (sent using POST), and return user information along side with the Auth-Key.
This Auth-Key is randomly generated after a call to /api/authenticate and stored in the backend users table with the specific user entry, a md5 hash of the remote ip + the user agent provided by the client.
On every request the value of Auth-Key, and the md5 sum mentioned, is searched for in users . If a valid user is found that has been active during the past N minutes the user will be granted access, if not: http return code 401.
In the REST client, first get the Auth-Key by posting to /api/authenticate, then store this value in a variable and send in on every future request.
If you want to stay true to the definition of a REST service then it should be stateless and not store any login (or other context specific) data on the server: http://en.wikipedia.org/wiki/Representational_state_transfer#Constraints
Your 2nd approach would fit this model
First decide what it is that you're protecting against:
Authentication? (Knowing who is requesting your service?)
Authorization? (Whether a given person can properly request a given service or not?)
I recommend that you provide hashed keys for your service. That way you can manage the key issue separately from the services. Or a client key and a secret, Amazon does this.
It is always easier for the client if you have a stateless protocol. And send everything through the parameters, cookies are a bother for the client too.
Remember that it is in your interest to make it as easy as possible for potential developers to use your service. A super secure service that no one uses is boring.
You can let clients choose the security level by giving them the choice of HTTP or SSL/HTTP endpoints to connect to. Client choice is a good thing.
Make users login by first sending credentials to a /login page with POST. The page sets a session cookie wherein the user is marked
as logged in, along with the permission level. On each following
request, I verify that the user is logged in and his/her permission
level. When the session expires, automatically or manually (logout,
the user will have to re-logon).
Temporarily save the credentials hashed locally and send the users credentials along every single request made by the user to verify the
credentials & permissions backend on a per-request basis.
Your first approach does not meat the statelessness constraint of REST. You cannot maintain client sessions on server side. This constraint makes REST highly scalable...
Your second solution is appropriate. The simplest way to use HTTP basic auth. You don't have to hash the password on client side. What you need is an encrypted connection. On server side you can have an [username, password] -> [identity, permissions] cache, so this solution is much faster and superior in every other way than having server side sessions.
By 3rd party (non-trusted) clients the authentication is more complex, I guess you don't need that part.
I'm no security-expert. I use the RESTful Play!-webframework and they do the following things to authenticate users.
The cookie is protected against manipulation. It is signed with a long secret key and is checked for each request. Just hashing it is not enough!
They recommend to set unique information the identify the user in the cookie. As the server should be the only one to manipulate the cookie, that's enough.
Don't put the password as credential in the cookie. If someone sniffs the cookie, not only the session can be hijacked, but also the complete account or even worse, other accounts with the same credentials.
If you want to protect the cookie against hijacking using https.