今天看了codeproject上面的一片文章,感觉不错。作者主要是用form authentication 实现了基于角色的认证。功能还算可以,基本可以代替MS 的Membership了,但是没有membership那么庞大。做一个基本的应用是够用了。
翻译一下大概内容,大意记录如下:
作者实现了4个网页,功能是:添加用户,给用户指定角色,删除角色,管理角色。
The Classes Overview
There are 4 classes: User
, Role
, SitePrincipal
and SiteIdentity
. I would like to overview the classes' methods and properties here:
The User class
User() | Default parameter less constructor to create a new user |
User(int userID) | This constructor gets a userID and looks up the user details from the database |
User(string email) | This constructor gets an email and looks up the user details from the database |
GetUsers() | This method returns a DataSet of all the users available in the database |
GetRoles() | This method returns a DataSet of roles assigned to the current user |
GetUserRoles(int userID) | This static method grabs the userID and returns a roles ArrayList assigned to that user |
AddToRole(int roleID) | This method assigns a role to the current user |
RemoveFromRole(int roleID) | This method removes current user from the role that has been passed by the roleID . |
Add() | Adds a new user to the database |
Update() | Updates current user information |
Delete() | Deletes current user |
UserID | Gets/Sets user's id number |
FullName | Gets/Sets user's full name |
Email | Gets/Sets user's email |
Password | Gets/Sets user's password |
Biography | Gets/Sets user's biography |
DateAdded | Gets/Sets user's registering date |
The Role class
Role() | Default parameter less constructor to create a new role |
Role(int roleID) | This constructor gets a roleID and looks up the role details from the database |
GetRoles() | This method returns a DataSet of all roles available in the database |
Add() | Adds a new role to the database |
Update() | Updates current role information |
Delete() | Deletes current role |
RoleID | Gets/Sets role ID number |
RoleName | Gets/Sets role name |
The SitePrincipal class (implements the IIPrincipal Interface)
SitePrincipal(int userID) | This constructor gets a userID and looks up details from the database |
SitePrincipal(string email) | This constructor gets an email and looks up details from the database |
IsInRole() | (IIPrincipal.IsInRole() ) Indicates whether a current principal is in a specific role |
ValidateLogin() | Adds a new user to the database |
Identity | (IIPrincipal.Identity ) Gets/Sets the identity of the current principal |
Roles | Gets the roles of the current principal |
The SiteIdentity class (implements the IIdentity Interface)
SiteIdentity(int userID) | This constructor gets a userID and looks up the user details from the database |
SiteIdentity(string email) | This constructor gets an email and looks up the user details from the database |
AuthenticationType | (IIdentity.AuthenticationType ) Always returns "Custom Authentication " |
IsAuthenticated | (IIdentity.IsAuthenticated ) Always returns true |
Name | (IIdentity.Name ) Gets the name of the current user |
Email | Gets the email of the current user |
Password | Gets the password of the current user |
UserID | Gets the user ID number of the current user |
Enabling Forms Authentication
为了实现ASP.NET Forms 认证, web.config 文件配置如下:
<configuration>
<system.web>
<authentication mode="Forms">
<forms name="RolesBasedAthentication"
path="/"
loginUrl="/Login.aspx"
protection="All"
timeout="30">
</forms>
</authentication>
</system.web>
</configuration>
forms的name属性指定了浏览器的cookie名字,默认的名字是.aspxauth,但是当在相同的服务器中有好几个应用程序,就应当一个不同的名字。loginurl是登录页面。timeout指定了cookie的有效时间,单位是分钟。当然了,对于要保存的cookie就无效了。protection是cookie的保存方法:all意味着数据会被加密和验证。别的可以指定的值包括:none,encryption,validation.
表单认证一旦被指定,每次用户请求一个页面,表单就要检查浏览器的cookie值。如果找到了,user identify就会以FormsIdentity类的形式保存在cookie中,这个类包含了认证用户的如下信息:
AthenticationType
- returns the value
Forms
IsAthenticated
- returns a boolean value indicating where the user was authenticated
Name
- Indicates the name of an authenticated user
因为FormsIdentity类只包含了用户的name属性,但是我们往往需要大量的信息,而不止于Name。因此我就写了这个SiteIdentity类,它实现了IIdentity接口,包含了认证用户的更多信息。
Creating the Login Page
登录页面包含两个文本框让用户输入电子邮件和密码,也许还可以放一个选项框,让用户选择是否要保持永久cookie,最后放一个submit按钮,Onclick事件处理如下:
private void Submit_Click(object sender, System.EventArgs e) { // call the ValidateLogin static method to // check if the email and password are correct // if correct the method will return a new user else return null SitePrincipal newUser = SitePrincipal.ValidateLogin(Email.Text, Password.Text); if (newUser == null) { ErrorMessage.Text = "Login failed for " + Email.Text; ErrorMessage.Visible = true; } else { // assign the new user to the current context user Context.User = newUser; // set the cookie that contains the email address // the true value means the cookie will be set persisted FormsAuthentication.SetAuthCookie( Email.Text, true ); // redirect the user to the home page Response.Redirect("Default.aspx"); } }
Authenticating User On Every Request
主要是实现了一个所有页面都要继承的基类,所有继承自它的页面都会包含我们自定义的SiteProcipal实例信息:
public class PageBase: System.Web.UI.Page { public PageBase() { } protected override void OnInit(EventArgs e) { base.OnInit(e); this.Load += new System.EventHandler(this.PageBase_Load); } private void PageBase_Load(object sender, System.EventArgs e) { if (Context.User.Identity.IsAuthenticated) { if (!(Context.User is SitePrincipal)) { SitePrincipal newUser = new SitePrincipal( Context.User.Identity.Name ); Context.User = newUser; } } } }
以后所有的页面都要继承自此页,而非System.Web.UI.Page,因此,如果此时想得到用户的信息就简单了:
或者你可以查看当前用户的角色:
if (Context.User.Identity.IsAuthenticated) { // if user is not in the Site Admin role, // he/she will be redirected to the login page if (!((SitePrincipal)Context.User).IsInRole("Site Admin")) Response.Redirect("Login.aspx"); }
The Demo Application
下载地址如下: