使用 forms 身份验证,避免重复造轮子

    最近开始一个小 asp.net 项目,整个项目需要登录才能操作。以前大家都采用 asp 的方式 session + cookie  来实现身份验证,我一直对 asp.net 自带的 forms 验证早就耳闻,苦于没实践,今天刚好逮到机会实际应用一下。
    问题:大家都说使用 forms 验证无法得到当前登录用户除了用户名之外的更多信息,经过我的一番小试验,在 forms 方式下自带的 userdata 可以为我们施展天地的地方。下面记录一下我的操作步骤备忘。

step 1: web.config 配置关键地方:
web.config配置
 1        <!--
 2            通过 <authentication> 节可以配置 ASP.NET 用来 
 3            识别进入用户的
 4            安全身份验证模式。 
 5        -->
 6    <authentication mode="Forms">
 7      <forms loginUrl="login.aspx" defaultUrl="index.aspx"
 8             name=".ztinfozero" path="/Manager" 
 9             slidingExpiration="true" timeout="10"></forms>
10    </authentication>
11    <authorization>
12      <deny users="?"/>
13    </authorization>
14

    <!-- 实现自定义的 rolemanager 后需配置 :
    <roleManager defaultProvider="providerName(类名)"
        cookieName="role" cookiePath="/" enabled="true"
        cookieTimeout="30"  cookieSlidingExpiration="true"
        cookieRequireSSL="false" cookieProtection="All"
        cacheRolesInCookie="true">
      <providers>
        <clear />
        <add name="providerName(类名)" type="providerName(类名)" />
      </providers>
    </roleManager>
    -->


step 2: 构造 SiteUser Model

TopicUser Model
[Serializable]
    
public class TopicUser
    
{
        
public TopicUser() { }

        
model 
    }


step 3: 创建用户登录代码:

数据库-用户登录方法


step 4 : 创建登录页:

代码
protected void btnOK_Click(object sender, EventArgs e)
        
{
            
string username = tbname.Text.Trim();
            
string pass = tbpass.Text.Trim();
            
if (!string.IsNullOrEmpty(username)) {
                
if (!string.IsNullOrEmpty(pass)) {
                    DataService.User b 
= new DataService.User();
                    DataService.TopicUser user 
= b.UserLogon(username, pass);
                    
if (user != null{
                        
//roles , userid | userchname 
                        string userdata = string.Format("{0},{1}|{2}",
                                user.UserPermit, user.autoID, user.UserChName);
                        
                        FormsAuthenticationTicket ticket 
= new FormsAuthenticationTicket(
                            
1, username, DateTime.Now, DateTime.Now.AddHours(2),
                            
true, userdata);
                        
string encticket = FormsAuthentication.Encrypt(ticket);
                        HttpCookie cookie 
= new HttpCookie(
                                    FormsAuthentication.FormsCookieName, encticket);
                        Response.Cookies.Add(cookie);
                        Response.Redirect(
"Index.aspx");
                    }


                }

            }

        }


step 5: 在 global.asax 里添加 Application_AuthenticateRequest 事件以设置当前登录用户的信息:

Application_AuthenticateRequest
/*****
using System;
using System.Security.Principal;
using System.Web;
using System.Web.Security;
****
*/


        
protected void Application_AuthenticateRequest(object sender, EventArgs e)
        
{
            HttpApplication app 
= (HttpApplication)sender;
            HttpContext context 
= app.Context;
            
if (context.Request.IsAuthenticated) {
                FormsIdentity id 
= context.User.Identity as FormsIdentity;
                FormsAuthenticationTicket ticket 
= id.Ticket;
                
string[] roles = ticket.UserData.Split(',');
                
/* 
                 * 将原有的Identity加上角色信息新建一个GenericPrincipal表示当前用户
                 * 这样当前用户就拥有了role信息
                 * 据此在web.config中用role来控制用户的访问权限了. 
                 
*/

                context.User 
= new GenericPrincipal(id, roles);
            }

            
old 
        }


step 6: 如何得到当前登录用户的信息

CurrentUser
        public static TopicUser CurrentUser {
            
get {
                DataService.TopicUser user 
= new DataService.TopicUser();
                FormsIdentity identity 
= HttpContext.Current.User.Identity as FormsIdentity;
                FormsAuthenticationTicket ticket 
= identity.Ticket;
                
string userdata = ticket.UserData;  //获取自定义的 UserData 串 
                
if (!string.IsNullOrEmpty(userdata)) {
                    
if (userdata.IndexOf(','> 0 && userdata.IndexOf('|'> 0)
                    
{
                        
//roles , userid | userchname 
                        string uinfo = userdata.Split(',')[1];
                        
string[] u = uinfo.Split('|');
                        
int uid = 0;
                        
int.TryParse(u[0], out uid);
                        user.autoID 
= uid;
                        user.UserChName 
= u[1];
                        user.UserName 
= HttpContext.Current.User.Identity.Name;
                    }

                }

                
return user;
            }

        }

    由此得到当前登录用户的  ID 为 UserBase.CurrentUser.autoID ; 真实名字是: UserBase.CurrentUser.UserChName ;
判断当前用户的角色是否为管理员: HttpContext.Current.User.IsInRole("1") ; // 1 为管理员

退出当前登录的方法:

LogOut.aspx
        protected void Page_Load(object sender, EventArgs e)
        
{

            System.Web.Security.FormsAuthentication.SignOut();
            Response.Write(
"<script>window.top.location='login.aspx';</script>");
            Response.End(); 
        }



    至此,身份验证完成。我们不用费尽心思在四处堆放用户是否登录判断的代码了。

 

 

posted on 2009-11-30 12:48  感恩的心  阅读(819)  评论(3编辑  收藏  举报

导航