User login over Api in Symfony2 - symfony

I am working on an API in symfony where users authenticate using a json web token. There is a bundle to provide this here: https://github.com/lexik/LexikJWTAuthenticationBundle.
There is documentation on the project page on how to set everything up. This bundle relies on the standard "form_login" configuration that is backed by the class defined in vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/FormLoginFactory.php.
The bundle provides success and failure listeners for authentication that short circuits the request and returns a JsonResponse with the token or an error with the appropriate response code.
Using the sample configuration on the project page, everything is working as described. The problem is that these predefined config factories such as "form_login" set cookies and many other behaviours that is not required in a stateless api.
The security component defines a config option "stateless" that is defined in the symfony book on security.
However the documentation above clearly states "If you use a form login, Symfony2 will create a cookie even if you set stateless to true."
The "form_login" has many options for redirecting or forwarding to the login page if the user is unauthenticated that isn't required for an api.
Also a lot of other functionality you may want to use, such as the SwitchUserListener is very much ingrained in the traditional development model where the server just returns html.
I'm looking to create a lightweight way to plug into symfony security using this bundle and disabling the other unneeded checks.
With JWT, no login is actually required, we need an unauthenticated route that we send a username and password to (over SSL) using the authorization header that returns the token. For the other protected routes we simply provide this token. This part is already provided by the bundle, I just need a stripped down way to get the initial token without invoking unneeded symfony code.
I found this example http://miguel.ibero.me/en/post/2012-04-04/symfony-rest-api.html which implements the code to get a token in a simple controller, bypassing the firewall.
I am looking for a better way to implement this using the firewall. I suspect I will have to create my own security factory such as "form_login".
I could use the http basic auth method to get the token, but I do not want symfony to present the username/password window. I would like the authenticator to check for the authorized header and simply return a message and response code whether it is successful or not.
Any suggestions appreciated.

I created my own bundle to deal with this: https://github.com/gfreeau/GfreeauGetJWTBundle

Related

Symfony 4 - Multiple authentication

Good afternoon,
Here I am working on Symfony 4 and on the Symfony Security module.
I need to customize the authentication of my users without using plugins such as Fosuser.
This is for the following reasons:
The user connects to a "main" server (ldap) with his login/password
I need to be able to retrieve his credentials to test his account on other ldap servers in parallel.
When the user is authenticated on the main one, the user is redirected to a page telling him if everything is ok or not on the other servers. In case it is not, he has the possibility to update his account.
But the documentation deals with "simple" cases and here I am a little lost.
I tested several possibilities (authentication with Guard, test of creation of a personalized provider...) without results.
I would need to understand the mechanisms of symfony authentication to create a custom authentication.
If anyone has a lead to guide me, that would be great.
Thank you in advance.
I think you need to divide your action into 2 stages:
Authenticate by LDAP against first server, i.e. with Symfony LDAP Component - this can be done by standard authentication form and FOSUserBundle
When you are already authenticated interact with second server in controller action. This can be done by writing entire code in Controler or in service designed to interact with this LDAP server. You can even use the same Symfony LDAP Component as before, but you will need to configure another instance of service by hand.

Asp.net core authorization redirect to specified path on failure

In "old" ASP.NET I could build a custom authorize attribute and override HandleUnauthorizedRequest. I cannot seem to do this with ASP.NET Core using a custom authorization handler. The latter either "succeed" or "fails" and I would like to redirect to alternative controller actions based on the nature of the failure.
Here's the scenario. Users of my web app have a claim which indicates that they are "active" users, i.e. they have fully registered and we have validated their details etc. New users have been authenticated using the OpenIdConnect middleware but, until we have fully validated and set up their account, do not have the "active" user claim. Thus, both new users and active users have been authenticated. I want to prevent new users accessing most of the application. Every time they try to get to https://app.example.com/dashboard I want to redirect them to a https://app.example.com/newuser page, from which they can go through the set up process.
I can use an authorization policy on my controllers to check for the presence of the "active" user claim and allow access. When a new user doesn't have this claim, and fails the authorization, I want the authorization handler to have some logic which then redirects them to an area of the app which they do have access to. But I cannot see how to do this using the authorization framework in ASPNET core.
There is a somewhat clunky solution which uses the CookieMiddleware and implements a handler for the OnRedirectToAccessDenied event - see https://github.com/aspnet/Mvc/issues/4890. I also thought about implementing an action filter which runs on every request.
Am I just being stupid here? Surely, it makes sense to want to carry out some action on authorization failures which doesn't just send the user off to re-authenticate.
After some digging about and referring to the wonderful book, Pro ASP.NET Core MVC (6th Edition, Adam Freeman), the simple answer to my question is to create an Authorization Filter. This implements IAuthorizationFilter with a single method OnAuthorization(AuthorizationFilterContext context). In this method do whatever you need to do to check the request. If it fails authorization simply set the context.Result property to some IActionResult, in my case RedirectToActionResult. If the request passes authorization do nothing.
You can also use dependency injection in the filter - fantastic.
There is no mention on how to implement or code samples for IAuthorizationFilter on the Microsoft ASP.NET docs site. Thanks are to Adam Freeman.

Token authentication and authorisation for a self-hosted ASP.NET Web API 2 REST service

I'm using VS2013 and Web API 2 to create a self-hosted (using OWIN), RESTful service over SSL using token authentication. Although I'm not a novice developer, this is my first time looking at ASP.NET technologies, so please keep that in mind.
I've got everything more-or-less working except for the authentication and authorisation parts. I fully understand the difference of authenticating a user (who is this user?) and authorising an already authenticated user to access a resource (can this user access this particular resource?).
A very simple overview of my auth process is as follows (makes some assumptions for brevity):
An unknown client connects to the API, e.g. GET api/values.
The server responds with a 401 and this response header: "WWW-Authenticate: Token".
Upon seeing this, the unknown client knows to connect to a different API endpoint here: POST api/auth (routed to the Login function), supplying the username and password.
The server will try to figure out if this is a valid user and can accept or reject the user depending on the validity of the credentials.
(Rejected) The server returns an error status code (403?). End of process.
(Accepted) The server creates a random token (e.g. a GUID) and stores it against the user record. Then it sends the token to the client.
The now authenticated client reconnects to the API, GET api/values, and this time also supplies the token.
The user returns the resource data to the client.
...
The user can log out by connecting to the same API as he used to log in: POST api/auth (this time, his request will be routed to the Logout function). This will remove the token from the server and the client will also have to remove its own token.
As you can see, this is a relatively simple process, but I can't find any concrete and simple examples to understand how best to achieve this with a self-hosted Web API 2.
I don't need to register users or do any password/roles management, etc. and there is no external authentication. All valid users have the same rights to access the resources and they're already created in the system by a separate process over which I have no control (I can only read their credentials for validation). Most examples I found are talking about security frameworks that I don't need, so I've ruled out using any of the following: Basic Authentication, Windows Authentication, Forms Authentication, Individual Accounts, ASP.NET Membership/Identity, OAuth, Thinktecture or any other security framework.
I've read articles about authenticating in a message handler and others about authentication in a custom Authorize attribute filter, while others even suggest I should use the new (in Web API 2) IAuthenticateFilter attribute. This is very confusing. Can you please advise on a very simple way to achieve my auth objectives? Any specific code examples will be greatly appreciated, even if they're just skeleton implementation or pseudocode. I just need some ideas to get me started.
After a lot of googling, I found this article on CodeProject: http://www.codeproject.com/Articles/630986/Cross-Platform-Authentication-With-ASP-NET-Web-API. While this is not Web API 2 or self-hosted, it has given me a number of ideas on how to proceed.
Someone also posted a comment to that CodeProject article referencing a NuGet package that may interest anyone looking for something similar: https://www.nuget.org/packages/WebApiTokenAuth. In my case, it is a bit much.
Finally, in addition to the authentication options mentioned in the question, there's also the option to write an OWIN middleware to do authentication if self-hosting using OWIN (as per the official MS recommendation). However, I plan to implement this particular form of token authentication with a message handler, as there's more support for this method available than for writing OWIN middleware.

Best practices for persisting user credentials in a Backbone.js based app?

I have a Backbone based app, which uses a Spring based backend.
The backend is secured using Spring security's implementation of http basic authentication and the user credentials are passed to the server in each request in accordance to REST.
Is there a secure way to store the credentials in the client?
I have tried several server based approaches, like remember-me feature, but it doesn't work with basic authentication, nor does it fit the definition of REST.
I've used cookies to hold on to user credentials object and that doesn't work too badly for the most part, although it can get a bit messy, and I'm not 100% sure how secure it is.
Store your user authentication in a cookie, and check for it when the router gets initialized. If the data is there, throw your authentication information onto your global application object app.user or something of the like.

Flex URLRequest and .NET authorization

can I make role based authorization when sending requests to an ASP.NET MVC backend system. I am calling action methods and expecting JSON results, however, some action methods are decorated with the [Authorize] attribute, others require some role privileges to be present. I certainly hope that passing authorization data with every request is possible
Unless the methods are designed to accept login information as parameters, you would typically have to login to the system by posting a form to the "login" action -- typically /account/login -- and from then on send the authorization cookie that you receive back with each new request to validate who you are. There are a lot of ways to configure the backend, though what I've described is the typical way. Fortunately, URLRequest has a way to specify that you want the HTTP stack to manage cookies for you, so this should be reasonably seamless from your end. NOTE: I've never used FLEX, I'm just going by the documentation.

Resources