[转载]使用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 @ 2012-12-15 17:25  火腿骑士  阅读(252)  评论(0编辑  收藏  举报