Asp.net core authorization redirect to specified path on failure - asp.net

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.

Related

How to use ASP.NET Identity 2.0 to register new users from mobile

I have an ASP MVC project with Identity 2.0 where users can sign up and register via the website through the Account Controller. I have a complimentary Android application where I want to access the same Account/Register post method.
I've tried creating a post method directly to /account/register, but I get an error that
"The required anti-forgery cookie "__RequestVerificationToken" is not present."
How can I adapt my existing account controller to allow the /account/register post to work from a non html client?
Thank you.
I think creating a new controller without anti forgery token attribute should do it. But I strongly suggest that for mobile clients you do a token based authentication system. Here is an excellent which explains step by step how to do that. http://bitoftech.net/2014/06/01/token-based-authentication-asp-net-web-api-2-owin-asp-net-identity/

Securing WCF service in an ASP.net financial application

I have an MVC4 ASP.net financial application with a WCF service. The current scenario isn't secure enough and I need you help with that.
The current scenario:
The user login using a login form, and I send his login details using a JSON object containing the UserID and the Password to the WCF service:
http://example.com:22559/Login
This returns a JSON object with a true or false.
If it's true, I use the ASP function
FormsAuthentication.SetAuthCookie(loginModel.UserID, loginModel.RememberMe);
to set authorization cookies to use it later.
When the user adds a new Transaction I send a JSON object containing the transaction details without the password to:
http://example.com:22559/AddTransaction
I depend here that the MVC controller will not allow the user to access the transaction page if he isn't logged in.
The problem is anyone can now sneak-out and add a transaction without entering the password!, using the URL:
http://example.com:22559/AddTransaction
What I need to do now, is to make the WCF service itself secured, but I don't know how to do that without making the user enter his username and password each time he adds a new transaction!, so, what is the proper way to do that?
Thanks in advance.
MVC 4's controllers typically use MemberShipProvider for authentication and RoleProvider for authorization. So your WCF services may share the providers.
For authentication, you don't need to do anything in WCF codes. For authorization, it is handy to decorate respective operation implementation function (not interface) with PrincipalPermissionAttribute with the Role name defined. The rest will be done in config and by runtime.
For more details, just search "membershipprovider wcf", you will find a lot articles/tutorials in MSDN, CodeProject and StackOverflow.
Please be mindful that in MVC 5 if you will be moving to MVC5, Identity 2.0 is used by default, and MembershipProvider and RoleProvider will not be their by default. Nevertheless, your WCF codes should remain unchanged, and only some elements under ServiceModel will need to adapt the new custom authentication and authorization, and the client codes should remain the same as well, no config change needed.

User login over Api in Symfony2

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

Need help understanding ASP .Net MVC user authentication/authorization

I have been going around in circles trying to properly understand this.
I have an ASP .Net MVC project I am working on and need to implement user logins that authorize and authenticate against en external system (via webservice).
I can't seem to get my head around MembershipProvider and AuthorizeAttribute in the context that I require.
Which do I need to use (I believe its both) and where do I need to customize to provide the authentication against an external system.
There is one additional thing I also require on top of the default ASP .Net user principals in that the external webservice will return a session ID upon successful login that would be used for subsequent requests to external services.
Would someone be able to point me in the direction of some useful example of this sort of set up?
MembershipProvider is used to provide the users that may login the system. The RoleProvider is used to tell which roles a user has. They are used during the authentication process. i.e. identifying the user. You can read about membership vs roles
The [Authorize] attribute on the other hand is used during authorization. i.e. to check if the user is allowed to do something.

Authentication through a token pass in ASP.NET MVC

I'm working on a solution to part of my companys site that is done in 2 different languages. My part of the project is in ASP.NET, and the login portal is in a different language.
We pass authentication credentials by storing login information in the database on the portal page and then sending a corresponding token to the URL in the page written in .NET. Almost all the tutorials and articles I've read about security for ASP.NET, and most languages, the message has generally been "just use the built in stuff and don't mess with it".
I have code that takes the token, goes into the database and gets the user details.. what do I do then to integrate that into the built-in security stuff for ASP.NET? I'd like to ultimately use Action Filters for authorization on my controllers. Thanks.
Once you get the user details you could emit an authentication cookie:
FormsAuthentication.SetAuthCookie("username", false);
This will append a cookie to the response so now the user will be authenticated and you can safely redirect to a controller action decorated with the [Authorize] attribute.

Resources