.Net之美读书笔记14
Asp.net 的验证和授权
Asp.net为用户提供了一套验证机制,用户只需要遵守就可以。用户需要明白验证流程就可以了
- 用户输入用户名和密码是否有效检验
- 为有效用户创建cookie
HttpCookie authCookie = FormsAuthentication.GetAuthCookie(userName, true)
- 利用创建的cookie 得到票据ticket
FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(authCookie.Value);
- 将票据ticket转换为cookie并输出
authCookie.Value = FormsAuthentication.Encrypt(newTicket);HttpContext.Current.Response.Cookies.Add(authCookie);
- 如果按照前四步,则asp.net内部处理了登陆状态;可以调用
Request.IsAuthenticated
是否认证,获取用户信息FormsIdentity identity = User.Identity as FormsIdentity;string userName = User.Identity.Name;
基本验证
- 新建一空的webForm站点
- web.config
<authentication mode="Forms">
<forms timeout="600" slidingExpiration="true" loginUrl="~/SignIn.aspx" />
</authentication>
- Login.aspx
<form id="form1" runat="server">
<asp:LoginView ID="LoginView1" runat="server">
<LoggedInTemplate>
<asp:LoginName ID="LoginName1" runat="server" />
,你已经登录了^_^
<br />
<br />
你可以选择
<asp:LoginStatus ID="LoginStatus1" runat="server" LogoutPageUrl="~/Logout.aspx" LogoutAction="Redirect" />
</LoggedInTemplate>
<AnonymousTemplate>
用户名:<asp:TextBox ID="txtUserName" runat="server" Width="128px"></asp:TextBox>
<br />
密 码:<asp:TextBox ID="txtPassword" runat="server"></asp:TextBox>
<br />
<asp:Button ID="btnLogin" runat="server" Text="登 录" OnClick="btnLogin_Click" Width="100px" />
<br />
<br />
<asp:Label ID="lbMessage" runat="server" ForeColor="Red" Text=""></asp:Label>
</AnonymousTemplate>
</asp:LoginView>
</form>
code:
public partial class Login : System.Web.UI.Page
{
private enum LoginResult
{
Success,
UserNotExist,
PasswordWrong
}
// 用户登录
private LoginResult CheckUser(string userName, string password)
{
string validPassword = "123"; // 包含正确的密码
string validUserName = "sa";
// 判断用户名是否正确
if (validUserName.Equals(userName))
{
// 判断密码是否正确
if (password.Equals(validPassword))
return LoginResult.Success;
else
return LoginResult.PasswordWrong;
}
// 用户名不存在
return LoginResult.UserNotExist;
}
protected void btnLogin_Click(object sender, EventArgs e)
{
TextBox txtUserName = LoginView1.FindControl("txtUserName") as TextBox;
TextBox txtPassword = LoginView1.FindControl("txtPassword") as TextBox;
Label lbMessage = LoginView1.FindControl("lbMessage") as Label;
string userName = txtUserName.Text;
string password = txtPassword.Text;
LoginResult result = CheckUser(userName, password);
string userData = "登录时间" + DateTime.Now.ToString();
if (result == LoginResult.Success)
{
SetUserDataAndRedirect(userName, userData);
}
else if (result == LoginResult.UserNotExist)
{
lbMessage.Text = "用户名不存在!";
}
else
{
lbMessage.Text = "密码有误!";
}
}
// 添加自定义的值,然后导航到来到此页面之前的位置
private void SetUserDataAndRedirect(string userName, string userData)
{
// 获得Cookie
HttpCookie authCookie = FormsAuthentication.GetAuthCookie(userName, true);
// 得到ticket凭据
FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(authCookie.Value);
// 根据之前的ticket凭据创建新ticket凭据,然后加入自定义信息
FormsAuthenticationTicket newTicket = new FormsAuthenticationTicket(
ticket.Version, ticket.Name, ticket.IssueDate,
ticket.Expiration, ticket.IsPersistent, userData);
// 将新的Ticke转变为Cookie值,然后添加到Cookies集合中
authCookie.Value = FormsAuthentication.Encrypt(newTicket);
HttpContext.Current.Response.Cookies.Add(authCookie);
// 获得 来到登录页之前的页面,即url中return参数的值
string url = FormsAuthentication.GetRedirectUrl(userName, true);
Response.Redirect(url);
}
}
- Default.aspx
<form id="form1" runat="server">
<asp:LoginView ID="LoginView1" runat="server">
<AnonymousTemplate>
欢迎访问, 游客 !
</AnonymousTemplate>
<LoggedInTemplate>
你好,
<asp:LoginName ID="LoginName1" runat="server" />
!
<br />
<strong>UserData值:</strong>
<asp:Literal ID="lbUserData" runat="server" />
</LoggedInTemplate>
</asp:LoginView>
<br />
<asp:LoginStatus ID="LoginStatus1" runat="server" LogoutPageUrl="~/Logout.aspx" LogoutAction="Redirect" />
<asp:Label ID="userName" runat="server"></asp:Label>
</form>
code
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
if (Request.IsAuthenticated)
{
FormsIdentity identity = User.Identity as FormsIdentity;
string userName = User.Identity.Name;
string userData = identity.Ticket.UserData;
Literal lbUserData = LoginView1.FindControl("lbUserData") as Literal;
lbUserData.Text = userData;
}
}
}
自定义IIdentity和IPrincipal接口,获取更多的用户信息
- 添加App_code文件夹,其下添加文件CustomIdentity.cs、CustomPrincipal.cs
public class CustomPrincipal: IPrincipal
{
private CustomIdentity identity;
public CustomPrincipal(CustomIdentity identity)
{
this.identity = identity;
}
public IIdentity Identity
{
get
{
return identity;
}
}
public bool IsInRole(string role)
{
return false;
}
}
public class CustomIdentity: IIdentity
{
private FormsAuthenticationTicket ticket;
private HttpContext context = HttpContext.Current;
public CustomIdentity(FormsAuthenticationTicket ticket)
{
this.ticket = ticket;
}
public string AuthenticationType
{
get { return "Custom"; }
}
public bool IsAuthenticated
{
get { return true; }
}
public string Name
{
get
{
return ticket.Name;
}
}
public FormsAuthenticationTicket Ticket
{
get { return ticket; }
}
// 这里可以是任意来自数据库的值,由Name属性取得
// 需要注意此时已通过身份验证
public string Email
{
get
{
HttpCookie cookie = context.Request.Cookies["Email"];
if (cookie == null || String.IsNullOrEmpty(cookie.Value))
{
string email = "m3321414@163.com"; // 实际应根据name属性从数据库中获得
cookie = new HttpCookie("UserType", email);
context.Response.Cookies.Add(cookie);
}
return cookie.Value;
}
}
//添加的属性
public string DeptName
{
get
{
HttpCookie cookie = context.Request.Cookies["DeptName"];
if (cookie == null || String.IsNullOrEmpty(cookie.Value))
{
string DeptName = "开发部门"; // 实际应根据name属性从数据库中获得
cookie = new HttpCookie("UserType", DeptName);
context.Response.Cookies.Add(cookie);
}
return cookie.Value;
}
}
}
- Global.asax文件下添加认证模块
protected void Application_OnPostAuthenticateRequest(object sender, EventArgs e)
{
IPrincipal user = HttpContext.Current.User;
if (user.Identity.IsAuthenticated
&& user.Identity.AuthenticationType == "Forms")
{
FormsIdentity formIdentity = user.Identity as FormsIdentity;
WebAppEmpty.App_Code.CustomIdentity identity = new CustomIdentity(formIdentity.Ticket);
CustomPrincipal principal = new CustomPrincipal(identity);
HttpContext.Current.User = principal;
Thread.CurrentPrincipal = principal;
}
}
- 页面获取数据
CustomIdentity identity = User.Identity as CustomIdentity;
if (identity != null)
{
// 获得UserData中的值
string userData = identity.Ticket.UserData;
Literal lbUserData = LoginView1.FindControl("lbUserData") as Literal;
lbUserData.Text = userData;
lbEmail.Text = identity.Email;
lbDeptName.Text = identity.DeptName;
}
通过用户ID获取用户信息
添加一个根据用户ID,获取用户信息的方法。每次获取调用。