HttpContext.Current.User用户对象表示用户的安全上下文,代码当前即以该用户的名义运行,包括用户的标识(IIdentity)和它们所属的任何角色。所有用户对象都需要实现 IPrincipal 接口。(MSDN)
创建一个User类实现IIdentity接口 重写相应的方法
public
class
User : IIdentity
{
private
int
_id;
private
string
_userName;
private
string
_password;
private
bool
_isAuthenticated;
#region
properties
public
virtual
int
Id
{
get
{
return
this
._id; }
set
{
this
._id
=
value; }
}
public
virtual
string
UserName
{
get
{
return
this
._userName; }
set
{
this
._userName
=
value; }
}
public
virtual
string
Password
{
get
{
return
this
._password; }
set
{
this
._password
=
value; }
}
//
是否通过认证
public
virtual
bool
IsAuthenticated
{
get
{
return
this
._isAuthenticated; }
set
{
this
._isAuthenticated
=
value; }
}
//
重写为用户ID
public
virtual
string
Name
{
get
{
if
(
this
._isAuthenticated)
return
this
._id.ToString();
else
return
""
;
}
}
public
virtual
string
AuthenticationType
{
get
{
return
"
CuyahogaAuthentication
"
; }
}
public
User()
{
this
._id
=
-
1
;
this
._isAuthenticated
=
false
;
}
}
创建一个CuyahogaPrincipal类实现IPrincipal接口
public
class
CuyahogaPrincipal : IPrincipal
{
private
User _user;
//
返回一个现实IIdentity接口的user对象
public
IIdentity Identity
{
get
{
return
this
._user; }
}
//
当前用户是否属于指定角色 在以后的权限认证中可以使用 也可以使用User类中的相关方法来代替
public
bool
IsInRole(
string
role)
{
foreach
(Role roleObject
in
this
._user.Roles)
{
if
(roleObject.Name.Equals(role))
return
true
;
}
return
false
;
}
///
初始化 若user通过授权则创建
public
CuyahogaPrincipal(User user)
{
if
(user
!=
null
&&
user.IsAuthenticated)
{
this
._user
=
user;
}
else
{
throw
new
SecurityException(
"
Cannot create a principal without u valid user
"
);
}
}
}
创建一个实现IHttpModule的AuthenticationModule类
public
class
AuthenticationModule : IHttpModule
{
private
const
int
AUTHENTICATION_TIMEOUT
=
20
;
public
AuthenticationModule()
{
}
public
void
Init(HttpApplication context)
{
context.AuthenticateRequest
+=
new
EventHandler(Context_AuthenticateRequest);
}
public
void
Dispose()
{
//
Nothing here
}
//
登录时 验证用户时使用
public
bool
AuthenticateUser(
string
username,
string
password,
bool
persistLogin)
{
//
数据访问类
CoreRepository cr
=
(CoreRepository)HttpContext.Current.Items[
"
CoreRepository
"
];
string
hashedPassword
=
Encryption.StringToMD5Hash(password);
try
{
//
通过用户名密码得到用户对象
User user
=
cr.GetUserByUsernameAndPassword(username, hashedPassword);
if
(user
!=
null
)
{
user.IsAuthenticated
=
true
;
//
string currentIp = HttpContext.Current.Request.UserHostAddress;
//
user.LastLogin = DateTime.Now;
//
user.LastIp = currentIp;
//
Save login date and IP 记录相关信息
cr.UpdateObject(user);更新用户授权通过信息
//
Create the authentication ticket
HttpContext.Current.User
=
new
CuyahogaPrincipal(user);
//
通过授权
FormsAuthentication.SetAuthCookie(user.Name, persistLogin);
return
true
;
}
else
{
//
log.Warn(String.Format("Invalid username-password combination: {0}:{1}.", username, password));
return
false
;
}
}
catch
(Exception ex)
{
throw
new
Exception(String.Format(
"
Unable to log in user '{0}':
"
+
ex.Message, username), ex);
}
}
///
<summary>
///
Log out the current user.注销用户
///
</summary>
public
void
Logout()
{
if
(HttpContext.Current.User
!=
null
&&
HttpContext.Current.User.Identity.IsAuthenticated)
{
FormsAuthentication.SignOut();
}
}
private
void
Context_AuthenticateRequest(
object
sender, EventArgs e)
{
HttpApplication app
=
(HttpApplication)sender;
if
(app.Context.User
!=
null
&&
app.Context.User.Identity.IsAuthenticated)
//
若用户已经通过认证
{
CoreRepository cr
=
(CoreRepository)HttpContext.Current.Items[
"
CoreRepository
"
];
int
userId
=
Int32.Parse(app.Context.User.Identity.Name);
User cuyahogaUser
=
(User)cr.GetObjectById(
typeof
(User), userId);
//
得到对应的cuyahogaUser对象
cuyahogaUser.IsAuthenticated
=
true
;
app.Context.User
=
new
CuyahogaPrincipal(cuyahogaUser);
//
将通过标准窗体认证的user替换成CuyahogaUser, cuyahogaUser包含更多的信息
}
}
}
登录时
protected
void
btnLogin_Click(
object
sender, System.EventArgs e)
{
AuthenticationModule am
=
(AuthenticationModule)Context.ApplicationInstance.Modules[
"
AuthenticationModule
"
];
if
(
this
.txtUsername.Text.Trim().Length
>
0
&&
this
.txtPassword.Text.Trim().Length
>
0
)
{
try
{
if
(am.AuthenticateUser(
this
.txtUsername.Text,
this
.txtPassword.Text,
this
.chkPersistLogin.Checked))
{
//
通过认证
Context.Response.Redirect(Context.Request.RawUrl);
}
else
{
//
认证失败
}
}
catch
(Exception ex)
{
}
}
}
退出登录用
protected
void
btnLogout_Click(
object
sender, System.EventArgs e)
{
AuthenticationModule am
=
(AuthenticationModule)Context.ApplicationInstance.Modules[
"
AuthenticationModule
"
];
am.Logout();
Context.Response.Redirect(Context.Request.RawUrl);
}
这样就实现了身份认证功能
然后可以方便的实现权限认证
在User类中实现相应的权限逻辑 如: 表示当前用户是否有权限浏览指定的节点
public
bool
CanView(Node node)
{
foreach
(Permission p
in
node.NodePermissions)
{
if
(p.ViewAllowed
&&
IsInRole(p.Role))
{
return
true
;
}
}
return
false
;
}
在Page代码中嵌入验证代码即可
User CuyahogaUser
=
this
.User.Identity
as
User;
if
(CuyahogaUser.CanView())
{
}
权限认证模块还是挺简单.
别忘了在web.config中对AuthenticationModule进行注册
分析代码来自Cuyahoga Created by jecray