I followed this code and implemented the jwt authentication successfully. I am using this authentication in my web application. I am able to get the token on the login page. After that how to attach that token to the header of all the subsequent requests. I stored the token in local storage, but when I navigate to next page after successful login before js loads, the page getting loaded with 401 error.
How should I achieve this?
The problem is you're trying to use token based security with the Web MVC architecture. I did a quick search for any tutorials on how to do it that way and all I was able to find is examples of REST APIs that use token based security.
The reason is that with Spring MVC, each link you click is going to redirect you to a controller endpoint that is going to render the HTML and send it back to the browser. Unless you somehow made every link on your site include the token in a header or perhaps used a cookie to store the token, you'll get a 401 error because the token isn't present in the request.
If you were to use Angular JS (or your favorite front end framework) with a REST backend, you'll be able to use the JS to put whatever you need in the header to make sure the user is authenticated and has access to the resource. There a lot of example projects out there that demonstrate how to do this.
Disclaimer I haven't been able to find a reliable source that definitively says that token based security is for REST only. I'm basing this on experience and readily what I see out there in terms of tutorials and how to articles.
Ich totally agree to the answer from blur0224, you have to set the token in the request header of every link on your pages. I don't know how to achieve this. Furthermore I think that JWT token based authentication is not the right way for MVC based app. I would use it in SPAs build with frameworks like Angularjs.
Why don't you use the 'standard' Spring authentication?
Related
I am working on a website which is developed in react js and I am fetching all data through the API calls. That API calls are visible in the network section of a browser and that API call contains JWT token in the header part of all API call, So it can cause security issue due to that anyone can do that API call with the same header and same URL through other platforms like postman n all.
So my question is that how can I control that no one else is able to access it or how can I hide that API calls from the network section of the browser?
Is there any other solution to solve this security issue?
You have to assign a token to each user. The token will be given to the user upon authentication.
You have to manage access to the page based on the userId and token.
Yo should not use generic tokens for all the users.
Destroy the token upon user logout.
If the user see the token on the network they can only have access to the portion that he is suppose to have access.
This is how I do it, hope it helps.
Trying to search for this results many many results for securing a WebAPI and how to secure an MVC application, but i could not find a solution.
What i want to achieve:
i have an MVC website with a modal Login form,
When the user enters he's credentials to the the form, an Ajax request is sent to a WebAPI with the credentials.
The WebAPI should return (i guess a ticket, since that is what i found).
The ticket would be then saved into the sessionStorage of the browser (no cookies),
Each page request to the website will check for the token, and enable/disable the parts that need to be secured.
All the examples i have found are showing either MVC only authentication,
or WebAPI authentication, but i could not find anything that does the described above.
The sessionStorage is available only for client-side use. You can manipulate or retrieve values from the storage using Javascript, but you can't directly read data from the server. Since MVC typically renders HTML Views server side, you have no options to send the token stored in the sessionStorage on each request.
The situation you described is an hybrid solution which can't be achieved without the use of cookies.
A simple solution is to set the login data (specifically the token if you will use a token-based approach) in a cookie issued by the Web API endpoint during the login phase.
I have been playing with Thinktecture IdentityServer3 and am keen to use it as the product looks great. However, I don't fully understand how to accomplish my flow which is probably fairly common:
Create Identity Server using Implicit flow
Setup an MVC web site
Setup a separate Web API
So far so good, as demonstrated in the examples on the site. I now wish to call the API using AJAX calls directly but for this i need an access token. It seems like a large overhead to have to route these through the MVC site itself (again, in the examples).
How can I accomplish this flow? Would it essentially blend the MVC and Javascript Client samples or is there a smoother way so the user only has to sign in once? Perhaps send the access token in a hidden field but then how would it renew?
Any help on understanding this would be great.
I've managed to come up with a solution which seems to work, not sure if it's best practice though...
Expose a method on the MVC site at AJAX/AccessToken
Method should be locked down with Authorize attribute to ensure the MVC part of the site is authenticating properly with IdentityServer
Method returns the users Access Token which was generated through the above call via MVC controllers
In JavaScript, simply use this endpoint to get an Access Token and then call the API manually
The call to get the Access Token should be secure as its within the same domain/authentication model as the MVC site itself
I've put up a sample here for anyone interested:
OIDC-Website
Check out the form post client to see the endpoints being called explicitly. You will need to hit the token endpoint to get your access token.
You should be able to use these endpoints in your AJAX calls, store the received claims and tokens in a cookie and take it from there.
Note that to renew the access token, you will also need to store the refresh token. The Implicit flow does not allow for refresh tokens (you'll need to use the Authorization Code Flow or the Hybrid Flow).
I'm currently running into a lot of issues with the CSRF token.
Our current setup is a Ruby API and an Angular front-end, both live on a different domain.
The Ruby back-end solely serves as an API for the front-end.
I've spend a lot of time researching this problem, but I can't find a proper solution.
So far the solutions I've found are:
Generate the token and insert it into the DOM (Different domains, so can't do that)
Let the API return the CSRF token on a GET request (Doesn't seem to work, and it's not a good solution since I don't want to make an extra request just to get the token)
So I'm rather stuck here and not sure how to continue.
Is the current implementation just not working? How do other people create an API with oauth without running into this issue?
Not sure if this will help but here is a sample of a simple todo api in ruby with angular as frontend, and i am using token for authentication generated after the user fills username and password.
https://github.com/sirfilip/todoapi/blob/master/app.rb (the api written in sinatra and sequel)
https://github.com/sirfilip/todoapiclient/blob/master/public/js/angular-todoapi-plugin.js (angular client api service that is used for communication with the api)
TL;DR: Secure your rails API with the doorkeeper gem.
This SO post seems to be the accepted answer when your api and client exist on the same domain.
In the post they outline the angularJS docs http://docs.angularjs.org/api/ng.$http :
Since only JavaScript that runs on your domain could read the cookie,
your server can be assured that the XHR came from JavaScript running
on your domain.
To take advantage of this (CSRF Protection), your server needs to set
a token in a JavaScript readable session cookie called XSRF-TOKEN on
first HTTP GET request. On subsequent non-GET requests the server can
verify that the cookie matches X-XSRF-TOKEN HTTP header
It seems that the security of storing and transferring the XSRF-TOKEN session cookie in this way hinges on having your api and your front-end be in the same domain. Since this is not the case, you may have to implement another form of authorization for any given client session, like OAUTH. I'd recommend taking a look at the doorkeeper gem. The gem will give you the ability to interact with your api as if you were any other client.
I have implemented an OAuth2 authentication mechanism in my GWT app. The OAuth2 server is based on Spring framework 3.x (using its Spring security OAuth2 implementation).
I am using the OAuth2 "Authorization code flow" to get the user authenticated (though implicit flow may have been a better choice in our case). So at first, the user is redirected to the OAuth2 server authentication page, he enters his credentials and if he is successfully authenticated, he is redirected back to a url with an oauth code. He will then make a second call to get an access token from the OAuth2 server.
Now, the issue is, we would like the user to be able to bookmark a page in the application and directly access it. If he has already authenticated then he would have direct access to it (no more auth involved). Otherwise, he would have to go into the OAuth2 authentication flow but in the end, should be redirected back to the bookmarked page he intended to access at the beginning.
How can I store this page url and get redirected to it after the user successfully authenticates ?
any help would be appreciated. Thanks!
EDITED
The initial url redirection is done via javascript's document.location.href
The way to maintain the original URI in an OAuth 2.0 Authorization Grant flow is to pass it in the state parameter so that the redirection endpoint can use it, after it exchange the authorization code for an access token, to redirect the user back to that URI.
FYI, this is exactly what Google suggests in the examples in their OAuth 2.0 documentation, e.g. https://developers.google.com/accounts/docs/OAuth2Login
Original answer:
The problem is using the hash part of the URL for the place, which is not sent to the server and thus cannot be used in the redirection to the OAuth2 server authentication page.
You have 2 (maybe 3) solutions:
stop using the hash for the place and switch to HTML5 History; either through gwt-pushstate at the History level, or a custom PlaceHistoryHandler.Historian if you use the Places API. That limits your audience though: http://caniuse.com/history
stop using an HTTP redirect, and instead use JavaScript so you can put the hash in the OAuth2 redirect_uri. So instead of redirecting, send an error page with the appropriate scripts bits.
some browsers append the hash to the URL after a redirection, so your OAuth2 server might be able to pick it (in JavaScript) and append it to the redirect_uri. That might depend on the HTTP status code used for redirecting (from experience, it works with a 301, but you don't want a 301 here). Needs testing.
You can do this using GWT activities and places.