使用asp.net mvc3的Filter模拟实现http basic Authentication

近段时间,在编写一个淘宝家园的手机客户端,需要一个配套的api提供服务,使用http basic验证来确认用户。在iis7上架了一个api的测试站点,iis默认的http basic 验证需要和windows的用户绑定在一起,无法将用户认证和业务数据中的用户进行对应关联。查询相关资料后,准备使用mvc的filter模拟实现http basic authentication,也方便在实现api时对验证和非验证的调整。
1.vs2010中建立asp.net mvc3 web项目
image
2.添加用户验证filter,重载OnAuthorization(AuthorizationContext filterContext)函数,实现basic验证
public class HttpBasicFilter:AuthorizeAttribute
    {
        public override void OnAuthorization(AuthorizationContext filterContext) {
            if(validateUser(filterContext)){
                return;
            }
            //设置http header信息
            SendAuthenticationHeader();
            filterContext.HttpContext.Response.Write(unAuthMessage);
            //中指处理,直接返回
            filterContext.Result = new EmptyResult();
        }
        private Boolean validateUser(AuthorizationContext filterContext)
        {
            try
            {
                string authHeader = filterContext.HttpContext.Request.Headers["Authorization"];
                if (authHeader != null && authHeader.StartsWith("Basic")) {
                    string[] auths = ExtractCredentials(authHeader);
                    string uname = auths[0];
                    string upwd = auths[1];
                    //密码校验
                    weibo_unitaoEntities1 db = new weibo_unitaoEntities1();
                    if (db.Userinfo.Where(c => c.uname == uname && c.upwd == upwd && c.ustatus == 0).Count() == 1)
                    {
                        filterContext.Controller.ViewData.Add("username", uname);
                        return true;
                    }
                }
            }
            catch (Exception ex) {
                //do something...
            }
            return false;
        }
        //获取用户名和密码
        private string[] ExtractCredentials(string authHeader)
        {
            //剔除 "basic"
            string encodedUserPass = authHeader.Substring(6).Trim();
            //字符编码
            string userPass = System.Text.Encoding.Default.GetString(Convert.FromBase64String(encodedUserPass));
            int separator = userPass.IndexOf(':');
            string[] credentials = new string[2];
            credentials[0] = userPass.Substring(0, separator);
            credentials[1] = userPass.Substring(separator + 1);
            return credentials;
        }
        //设置401错误
        private void SendAuthenticationHeader()
        {
            HttpContext context = HttpContext.Current;
            context.Response.StatusCode = 401;
            context.Response.AddHeader(
                "WWW-Authenticate",
                String.Format("Basic realm=\"{0}\"", "unitao"));
        }
        //错误页面信息
        private string unAuthMessage="<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd\">"
                                        +"<html>"
                                        +"<head>"
                                        +"<title>Error</title>"
                                        +"<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"/>"
                                        +"</head>"
                                        +"<body><h1>401 Unauthorized.</h1></body>"
                                        +"</html>";
        
}
 
 
3.在需要basic Aathentication为controller添加filter,也可以针对某个action加上filter
image
 
4.发布后需要开启站点的匿名登录模式(或者在webconfig中配置)
image
 
 

posted on 2011-06-11 09:29  agefish  阅读(1035)  评论(0编辑  收藏  举报