一式を https://github.com/ken200/OwinAuthWithNancy に配置しています。
認証関係のソースコードは UserManager.cs に記載しています。
「独自認証」仕様
-
ユーザー情報としては、「ユーザー名」のみ使用する。後述するが、ユーザーIDも持つ必要あり。しかし、使わないので適当な値をセットしている。
-
パスワードチェックは行わない。
-
ユーザー名が非管理者的な名称("admin","root"以外)の場合にログイン許可する。
参照したWebページ
一般的な独自認証について知りたい。または、使用するフレームワークが ASP.NET MVC の場合は、こちらを参照したほうが断然よいです。
独自認証でのパスワードチェック関係で少しはまったポイントについても記述されています。
必要パッケージ
- Microsoft.AspNet.Identity.Core
ASP.NET Identityのコアパッケージ。
(余談ですが、MS製Webフレームワークは Microsoft.AspNet.* というネームスペースになります。)
構成物
Microsoft.AspNet.Identity.IUserインターフェイス実装クラス
ユーザー情報を表す。ユーザーIDとユーザー名が必須項目。
今回はIDが不要のため、オブジェクト生成する度にGUIDを割り付けているが、ふつうはこんなことしないので注意。
public class MyUser : IUser
{
public string Id { get; set; }
public string UserName { get; set; }
public MyUser()
{
Id = Guid.NewGuid().ToString();
}
}
Microsoft.AspNet.Identity.IUserStoreインターフェイス実装クラス
ユーザーストアを表す。このクラスでユーザー情報の登録・削除・更新、参照を行う。
パスワード情報も管理する場合は、IUserPasswordStoreインターフェイスの実装も行う必要あり。
public class MyUserStore : IUserStore<MyUser>
{
public MyUserStore(){}
public Task CreateAsync(MyUser user)
{
//何もしない
return Task.Delay(0);
}
public Task DeleteAsync(MyUser user)
{
//何もしない
return Task.Delay(0);
}
public Task<MyUser> FindByIdAsync(string userId)
{
//今回、ユーザーIDは利用しないので、呼び出されたらException吐く
throw new NotSupportedException("UserId is not supported");
}
private bool ExistUser(string userName)
{
if (userName.ToLower() == "admin" || userName.ToLower() == "root")
return false;
return true;
}
public Task<MyUser> FindByNameAsync(string userName)
{
//spec:「管理者っぽい名前(adminまたはroot)」は弾く
return Task.Run<MyUser>(() =>
{
return !ExistUser(userName) ? new MyUser() { UserName = userName } : null;
});
}
public Task UpdateAsync(MyUser user)
{
//何もしない
return Task.Delay(0);
}
public void Dispose()
{
}
}
Microsoft.AspNet.Identity.UserManagerクラス
IUserStore実装クラスを使ってユーザー管理を行うクラス。今回はこのオブジェクトを内包するファザードクラスを定義した。
CreateAsync()でSystem.Security.Claims.ClaimsIdentityクラスを取得し、これを使って認証登録処理が行われる。
public class MyUserManager
{
private UserManager<MyUser> _uMng;
public MyUserManager(UserManager<MyUser> uMng)
{
this._uMng = uMng;
}
public MyUserManager()
: this(new UserManager<MyUser>(new MyUserStore())) { }
public async Task<ClaimsIdentity> CreateAsync(string username)
{
var user = new MyUser() { UserName = username };
var activeUser = await _uMng.FindByNameAsync(user.UserName);
if (activeUser == null)
{
return await _uMng.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);
}
else
{
return null;
}
}
}