Search code examples
asp.net-mvcasp.net-mvc-4forms-authenticationbasic-authentication

Secure a single action with Forms Authentication & Basic Authentication simultaneously


My MVC application is secured using Forms Authentication. I have a global filter to which applies the AuthorizeAttribute.

I have a controller called Development with an action called Report. I can access this fine by authenticating in the normal way and going to http://localhost:8080/Development/Report. If I am not authenticated then it redirects me to the Forms Authentication login.

I am trying to embed this page into an iOS app so that a user can view the information without having to manually authenticate themselves. To confuse things the iOS app uses a different authentication system, however it holds a device ID and a unique token which my MVC app also store.

What I am trying to do is make the Report action available both via Forms Authentication and from the iOS app using basic authentication where the username will be the device ID and the password will be the token. It's really important that when authenticated using this method the user can only access the Report action. What's the best way to implement this whilst keeping everything secure?

I was thinking of marking the Report action with the AllowAnonymous attribute and then creating a custom authentication just for this action. Is this the best way?


Solution

  • Authentication strategies are just that: strategies. They're not intended to be mixed and matched; you pick one that best suits your application and go with it.

    That said, I see two ways forward. Either way, however, will not allow you to use the same action for everything. Your best bet is to factor out shared code into a utility class or similar.

    1. Put the two actions in separate projects. Then each project can implement its own auth strategy. Again, similar code can be factored out into a utility class, and in this case, shared via a class library that both projects may reference.

    2. Create a separate action in the same project and don't use Authorize on it or use AllowAnonymous if it's part of a controller that is authorized. This will essentially turn off the standard auth for this action and provide no protection. However, you're now freed up to do your own "authorization" manually. You can either check the values of device ID and token directly in the action or create an action filter that does so. Which you choose depends on how frequently you need to do this. If this is a one-off you might just want to check directly in the action as that will be quicker and easier. However, if it is one-off you may still want to use an action filter just so you're prepare should its use become more widespread.