I've started using backbone.js with ASP.NET MVC 3 lately.
My server exposes a RESTfull API that my website works against.
Meaning - the authentication works with a dedicated "authenticate service".
authentication token for the user stored in client cookie.
No forms authentication, Server is stateless, no session.
How do I implement a client only "Forms authentication" alike mechanism
(With 'return url' and all) ?
Is there any javascript framework for that ? or should I implement all the routing, cookie testing and validations manually ?
I implemented something similar at one point, though with a java backend. The solution consisted of:
Server checks that there is an authenticated session for all calls, returns 401 Unauthorized if there is no valid session with logged in user
I added a global jQuery.ajaxError handler, that checks the http code of the error, if it's 401 I used backbone routing to show the login screen
Login screen implemented with backbone view, on submit I send a ajax request to server, server checks credentials and creates session
The advantage of this approach is that I could use normal session / cookie handling on the server like in any app and only have authentication code in one place on the client.
Related
I'm using JWT authentication in my node site with passport and am not sure I am understanding the concepts.
Say I'm an authenticated user with my token saved in local storage. Say I then navigate to a /user page, which will display data about my user. Normally, I would check if the user is logged in, and if they are not, they would get redirected to a login page. But in this case, since I can't send the authentication token from a page request, I have to load my /user page, then the page makes a request for user data, and if the data is not found, I redirect them to the login page via javascript.
Am I correct in how I would handle this? It seems like a bad user experience, having to wait and redirect twice. Is there a way around this? Is JWT just not what I'm looking for my implementation?
If you want to render the page server side, you should set the JWT as a cookie instead of using local storage. You would be able to catch, verify and use it when a user request a page.
But I have to say that modern web applications use client side rendering. So there's no need to store the JWT as a cookie. When requesting a page, you will recieve only the static assets and you will get data by queryng an API that could response with 401 (Invalid or Expired Or Missing Token).
It seems you were using server side rendering before. Now you want to use JWT and you have read somewhere that a common practice is to store it in LocalStorage (that's true). Now you are dealing with a server side rendered application architecture while tryng to mix client side rndered applications concepts.
You are not doing huge errors, but you should consider to fully render your application server or client( I suggest ) side. For the second option, google "Build single page application"
I m working on an application that needs SAML to manage authentication with an OpenAM server.
Actually, I use Satellizer with OAuth2 implicit grant flow and I have the following :
Open angularjs app in browser
Click on the third party login button
A new window hover the existing one (with ng app) is open asking me my credentials
I fill them, and validate
The pages made its stuff (generating token)
The angularjs application gets the token through the windows (how it is possible ?)
I can use my application with the OAuth2 bearer / jwt token.
I need to have something that works the same using SAML. The fact is that I m completely lost and it seems that I should log onto the SAML server using my backend...
I don't really like this situation and I need to know if there's something better to do using client side application.
What is the "usual" authentication flow with client side app with SAML ?
Thanks for your help
SAML2 was designed at a time when the concept of client side apps with JavaScript was not yet invented.
A common method is to use an intermediate OpenID Connect/SAML2 proxy/bridge (e.g. IdentityServer3 + Kentor.AuthServices.Owin) to authenticate users:
User starts log in sequence in JS app.
User is redirected (part of OpenID Connect flow) to IdentityServer3.
User is redirected (part of SAML2P) to SAML2 Idp.
User authenticates at SAML2 Idp.
User is redirected back to IdentityServer3 (part of SAML2P).
User is redirected back to JS app (part of OpenID Connect flow).
This works excellent to get the user authenticated with an external Idp. If you have resources, such as backend services, those calls are usually authorized through an OAuth2 bearer token issued at step 6.
If your backend API is expecting a SAML assertion instead of a bearer token you will have to look at our ways though.
Implementation of user authentication in Angular app means that application's javascript must be available to user before he is authenticated. That is the problem. What is the correct way to make this happen with Angular? Do I need to implement a separate app for authentication and then redirect users to the base app?
Authentication should be on server level. The angular app should be responsible for only the capturing of credentials, possibly encrypting it, and sending an authentication request to the server with those credentials. The server response(possibly a token) could be used for any further communications with the server to identify the logged in user and its available services.
If the application itself does not contain any private business logic, I don't see value in keeping the application away from the end user even before authentication. On that note, however, take a look at tasks that are used to minify javascript code. This may be second best :)
I'm struggling with implementing a proper front-end auth solution for my de-coupled setup. It consists of the following:
Server-side Ruby API (using Warden for email/password auth)
Client-side Backbone.js app
I think I'm stuck at how to properly pass tokens from the server to the client.
This passage from staticapps.org explains the type of flow I'm looking to achieve:
The client directs the user to a server-side authentication process. This may be a JavaScript pop-up window or a browser redirect triggered by setting window.location.
The server authenticates the identity of the user via password, social sign-in, or other means.
The server creates a randomly generated token and associates it with the now authenticated user.
The server transmits the token back to the client.
The client includes the provided token on subsequent requests to the server as a proof of identity, granting the user access to protected resources.
Any ideas how to achieve this with Warden on the server?
Note
I should mention that I'm leveraging Rack::Session::Cookie which I assume will be the unique token that is passed back and forth?
Currently, my authentication flow is as follows:
User fills in a login form in the client browser app (AngularJS, to be precise), username and password are stored into the browser's memory (plain Javascript variables).
When accessing protected API resources, the request is authenticated with HTTP Basic Auth over SSL using the credentials stored in memory.
The problem is, when the user refreshes the page, her credentials are wiped out and she needs to sign in again. Am I missing something obvious here?
Few solutions I've found so far:
Store username and password into a cookie: this seems obviously insecure, even when using secure cookies and/or encryption.
Use session cookies: this seems to be against the RESTful principle of statelessness.
(I guess OAuth has the same problem with securely storing access tokens in the client?)
Session cookies are totally fine here. Once installed you dont care of them, browser will send them with each request via headers.
Inspired by this answer, I ended up doing something like this (link opens a rather large picture).
In short, client stores Access Token in a javascript variable, but Refresh Tokens are stored in a server-side session (on the server hosting our client app, not on the API server).