views:

786

answers:

2

Hi there, Is it possible to make my application ask for username and password prompting for it before render a view? Just like on twitter API to get information about your account:

http://twitter.com/account/verify%5Fcredentials.xml

So before render the view || file it asks you to insert you username and password, I think this is made directly on the server since the curl request is based on username:password as well like this:

curl -u user:password http://twitter.com/account/verify_credentials.xml

As I'm trying to build an API following the same structure I would like to know how I can do this on ASP.NET MVC C#. I've already used this on ruby rails and its pretty simple like:

before_filter :authenticate

def authenticate
    authenticate_or_request_with_http_basic do |username, password|
    username == "foo" && password == "bar"
end

I don't think that [Authorize] filter is the same since I believe it's just a redirection, and it redirects you to the Accounts Internal Controller that is based on the accounts database, in this case I will use another database, specifically from a webservice and do the validation after the information is submitted. But I need the action to require the user and pass credentials on its request.

Thanks in advance


UPDATE:

Actually to request a page that requires this authentication (i.e. Twitter) I would have to declare this on its request

request.Credentials = new NetworkCredential("username", "password");

And this would reflect that prompted username and password.

So, it's exactly the same thing but from the other side, if it's possible to provide information to the authentication prompt on request, how could I require this authentication on the request instead?

So everytime somebody tries to make a request to my application on example:

http://myapplication/clients/verify%5Fcredentials

it should ask for a username and password with that server prompt so to retrive information on curl for example it would be like this

curl -u user:password http://myapplication/clients/verify_credentials
+11  A: 

Well, to require basic authentication you need to return 401 status code. But doing that will cause the current authentication module to execute its default unauthorized handler (for forms authentication, this means redirecting to login page).

I wrote an ActionFilterAttribte to see if I can get the behaviour you want when there's no authentication module installed in web.config.

public class RequireBasicAuthentication : ActionFilterAttribute {
   public override void OnActionExecuting(ActionExecutingContext filterContext) {
       var req = filterContext.HttpContext.Request;
       if (String.IsNullOrEmpty(req.Headers["Authorization"])) {
           var res = filterContext.HttpContext.Response;
           res.StatusCode = 401;
           res.AddHeader("WWW-Authenticate", "Basic realm=\"Twitter\"");
           res.End();
       }
   }
}

And the controller action :

[RequireBasicAuthentication]
public ActionResult Index() {
    var cred = System.Text.ASCIIEncoding.ASCII
            .GetString(Convert.FromBase64String(
            Request.Headers["Authorization"].Substring(6)))
            .Split(':');
    var user = new { Name = cred[0], Pass = cred[1] };
    return Content(String.Format("user:{0}, password:{1}", 
        user.Name, user.Pass));
}

That action successfully prints the username and password I enter. But I really doubt that's the best way to do this. Do you have no choice except asking for username and password this way?

çağdaş
Yeah, thank you very much for your help çağdaş, but yes, unfortunately I can see that things are much more complicated when you speak about windows platform, at least is what I can say for now since, I'm not an expert on this. but this wont work since the request doesn't require username and password on itself, this would behave like a simple redirection and using curl on this url would result this instead a validation or not:<html><head><title>Object moved</title></head><body><h2>Object moved to <a href="%2fAccount%2fLogOn%3fReturnUrl%3d%252fclient%252fverify">here</a></h2></body></html>:(
ludicco
What makes me think, if its really possible to build a REST API based on URL call with ASP.NET and it doesn't seems to be possible unfortunately.
ludicco
This would only redirect if you have forms authentication enabled. I tested this with `authentication` part removed from `web.config` and it asked for username and password instead of redirecting.
çağdaş
+3  A: 

You really want to create a service and not a web application, based on what I have read. I am guessing here, but I think you picked ASP.NET MVC to take advantage of the routing and building the URL's the way you want? Correct me if I am wrong.

In my opinion the best way to solve the problem you are having is to build RESTful web services with WCF if you are returning data. This article should help you get started if you want to go this route.

Otherwise, you will need to go further up the stack for handling the request and authenticating it. If this is the case, I can help with providing more info and code.

Dale Ragan
Hi Dale, actually I think your answer is very good, yes, I'm trying to create this API with MVC because of its facility and because the main app resides on it as well, so this API would be an extension to use on another platforms such desktop application, mobile phones apps, etc. I know nothing about WCF but it seemed to be very good, a I'm pretty sure that would worth to try it.I seems to be much better than create a very complex structure to perform a simple job.Thanks again Dale
ludicco