# 共通ドキュメント

## 認証

### 概要

- 構成要素
- 設定
- パスワードのハッシュ
- 認証プロバイダーの使用方法
- 認証済情報保存装置の使用方法
- 実装済みの認証プロバイダー
- 実装済みの認証済情報保存装置
- 新しいデータ認証プロバイダークラスの作成(C#)
- 新しいデータ認証済情報保存装置クラスの作成(C#)

### 構成要素

認証機能を構成する要素

- 認証プロバイダー(AuthProvider)
- 認証済情報保存装置(AuthStorage)
- 認証情報(Identity)
- ユーザー情報(IUser)
- ロール(IAclRole)

#### 認証プロバイダー(AuthProvider)

ログインユーザーの正当性判定機能を提供する。

#### 認証済情報保存(AuthStorage)

認証済みのユーザー情報を格納する。

#### 認証情報(Identity)

認証済みユーザー、ユーザーに割り当てられたロール

#### ユーザー情報(IUser)

ユーザーを表す。

#### ロール(IAclRole)

ユーザーの役割を表す。

#### クラス図

##### 基本クラス

##### 実装

#### シーケンス図

##### ログイン

##### ログアウト

##### 処理中

### 設定

#### 設定項目

##### 基本設定項目

authenticate | 認証設定 セクション名
providerClass | 認証機能実装クラスを指定
storageClass | 認証済情報保存装置クラスを指定
hashMethod | パスワードハッシュ方法を定義(MD5|SHA|SMD5|SSHA) 空ならばハッシュなし(生パスワードを処理する)
sessionName | 認証済情報保存装置が使用する。認証情報を格納するASP.NETセッション名を設定
saltLength | SMD5,SSHAの際のSaltに使用するバイト列の長さを設定
encode | 保持するパスワードのエンコード方法 (PLAIN|HEX|BASE64)
connection | 認証のためのデータアクセス接続先

##### 設定例

データベース認証実装クラスを使用する。パスワードはMD5でハッシュした結果を16進表記の文字列で保存している。

    <authenticate
        providerClass="CFW.Auth.DatabaseAuthProvider,CFW.Auth"
        storageClass="CFW.Auth.DefaultAuthStorage,CFW"
        hashMethod="MD5"
        sessionName="__AUTH"
        saltLength="8"
        encode="HEX"
        connection="default"
        />

### パスワードのハッシュ

認証情報データの漏洩等の対策のため、保存されるパスワードは一方向ハッシュ関数を使用して誰にも復元できない状態にするべき。

#### ハッシュ方法

MD5 | パスワード保存時は、ユーザーパスワードを CFW.Util.Hash.MD5(string) を使用してハッシュして保存する。パスワード検証時は入力されたパスワードをCFW.Util.Hash.MD5(string) を使用してハッシュした値と保存している値を比較する。
SHA (SHA1) | パスワード保存時は、ユーザーパスワードを CFW.Util.Hash.SHA1(string) を使用してハッシュして保存する。パスワード検証時は入力されたパスワードをCFW.Util.Hash.SHA1(string) を使用してハッシュした値と保存している値を比較する。
SMD5 (SaltedMD5) | パスワード保存時は、(ユーザーパスワード + ランダムなSalt)を CFW.Util.Hash.MD5(string) を使用してハッシュした値にSaltを加えて保存する。パスワード検証時は保存しているパスワードからSaltを取り出し、(入力されたパスワード+Salt)をCFW.Util.Hash.MD5(string) を使用してハッシュした値 + Salt と保存している値を比較する。
SSHA (SaltedSHA1) | パスワード保存時は、(ユーザーパスワード + ランダムなSalt)を CFW.Util.Hash.SHA1(string) を使用してハッシュした値にSaltを加えて保存する。パスワード検証時は保存しているパスワードからSaltを取り出し、(入力されたパスワード+Salt)をCFW.Util.Hash.SHA1(string) を使用してハッシュした値 + Salt と保存している値を比較する。

#### ハッシュの計算式(概念)

    //1. 保存時(Saltなし)
    hashed = Hash(inputString)

    //2. 保存時(Saltあり)
    hashed = Hash(inputString + salt)
    savestring = hashed + salt

    //3. 検証時(saltなし)
    hashedString = Hash(inputString);
    if(hashedString == savedString) //OK
    else //NG

    //4. 検証時
    hashedString = Hash(inputString + salt) + salt
    if(hashedString == savedString) //OK
    else //NG

#### 実装(C#)

    //保存時
    //設定情報に基づき、最適はハッシュ関数を定義したPasswordHashのインスタンスを取得する。
    PasswordHash hash = PasswordHash.GetInstance();
    //設定情報のhashMethod、saltLengthを使って入力値をハッシュする。エンコードは設定情報のencodeによる。
    hashed = hash.Hash(inputString);

    //検証時
    PasswordHash hash = PasswordHash.GetInstance();
    //入力値のハッシュが保存値と同じかどうかの検証
    bool valid = hash.ValidateHash(inputString,savedString);

#### その他

「パスワードの暗号化(平文化可能なもの)」は考えない。暗号化ロジックが漏れた場合に対処できないから。

### 認証プロバイダーの使用方法

#### ユーザーログインの場合

- CFW.Auth.AuthProviderFactoryから設定に基づくAuthProviderインスタンスを取得する。
- AuthProvider#Authenticate() を呼び出しログインID,パスワードの正当性を検査する。

#### ユーザー認証後のユーザー情報取り出し

- CFW.Auth.AuthProviderFactoryから設定に基づくAuthProviderインスタンスを取得する。
- AuthProvider#GetIdentity() を呼び出し認証情報を取得する。

#### 現在使用中のユーザーが既に認証されているかの検査

- CFW.Auth.AuthProviderFactoryから設定に基づくAuthProviderインスタンスを取得する。
- AuthProvider#IsAuthenticated() を呼び出す。

#### ログアウト

- CFW.Auth.AuthProviderFactoryから設定に基づくAuthProviderインスタンスを取得する。
- AuthProvider#Logout() を呼び出す。

#### サンプル (ログイン処理)

    CFW.Auth.AuthProvider provider = CFW.Auth.AuthProviderFactory.GetInstance();
    bool result = provider.Authenticate(LoginId.Text,Password.Text);
    if(result){
        //ログイン出来たのでユーザーの最初のページに移動するetc...
        Response.Redirect("mypage.aspx");
    }
    else{
        //ログインできないのでもう一度ログイン画面を表示するか、エラー画面を表示、など
        //現在のページがログイン画面なら何もしない=ログイン画面再表示
        Message.Text = "ログインIDかパスワードをご確認ください。";
    }

#### サンプル (ユーザーページにログイン名を表示)

    CFW.Auth.AuthProvider provider = CFW.Auth.AuthProviderFactory.GetInstance();
    CFW.Auth.Identity identity = provider.GetIdentity();
    if(identity == null){
        //まだログインしていないかログインに失敗している
        Greeting.Text = "ログインしてください。";
    }
    else{
        //既にログインしているのでユーザーに挨拶文を表示する
        Greeting.Text = string.Format( "ようこそ {0} 様", identity.User.Name  );
    }

#### サンプル (ログインユーザーにのみ見せる情報のページ)

    CFW.Auth.AuthProvider provider = CFW.Auth.AuthProviderFactory.GetInstance();
    if(!provider.IsAuthenticated()){
        //ログインしていないので現在のページは見せずにログインを強制する。
        Response.Redirect("loginpage.aspx");
    }

#### サンプル (ログアウト)

    CFW.Auth.AuthProvider provider = CFW.Auth.AuthProviderFactory.GetInstance();
    provider.Logout();

### 認証済情報保存装置の使用方法

* 認証プロバイダーのみが認証済情報保存装置を使用する。クライアントアプリケーションから直接使用することはない。

認証プロバイダーからは認証済み情報の保存(SaveIdentity)、取り出し(GetIdentity)、破棄を呼び出す(RemoveIdentity)。

### 実装済みの認証プロバイダー

CFW.Auth.NullAuthProvider | テスト用。CFW.dllに定義。ログインID=nulluser,パスワード=nulluserで使用する。
CFW.Auth.DatabaseAuthProvider | データベース上に"auth_users"テーブルを作成して使用する。CFW.Auth.dllに定義。ACL情報のために"acl_roles","auth_users_roles"テーブルと設定データが必要

#### CFW.Auth.DatabaseAuthProviderのためのテーブル設定

    --ログインユーザー情報テーブル
    create table dbo.auth_users(
        login_id varchar(64) not null,
        name varchar(100) not null,
        password varchar(100) not null,
        description varchar(500),
        constraint pk_auth_users primary key(login_id)
    )
    go
    --ユーザーロールテーブル
    create table dbo.acl_roles(
      id int not null,
      name varchar(100) not null,
      parent_id int,
      left_side int,
      right_side int,
      description varchar(500),
      constraint pk_acl_roles primary key(id)
    )
    go

    --ログインユーザーとユーザーロールの紐付けテーブル
    create table dbo.auth_users_roles(
      id int not null,
      login_id varchar(64) not null,
      acl_roles_id int,
      description varchar(500),
      constraint pk_auth_usesr_roles primary key(id)
    )
    go

上記テーブルを作成し、必要データを登録。ACLについてはアクセス制御の項参照

### 認証済みの認証済情報保存装置使用方法

CFW.Auth.DefaultAuthStorage | staticなデータ上に認証済み情報を保持する。従ってウェブアプリケーションには使用できず、クライアントサイドアプリケーションのみで使用する。
CFW.Web.Auth.SessionAuthStorage | asp.netセッションオブジェクト上に認証済み情報を保持する。asp.netセッションオブジェクトの持続時間以上は保持できない。
CFW.Web.Auth.AutoLoginAuthStorage |

### 新しいデータ認証プロバイダークラスの作成(C#)

#### クラス定義

CFW.Auth.AuthProviderクラスを継承し、LoadIdentityメソッドとVerifyCredentialメソッドを実装する。

CFW.Auth.AuthProvider#Authenticate は デフォルト実装を持ち以下の処理を実装している。

- VerifyCredentialメソッドを呼び出す。
- VerifyCredentialメソッドがtrueを返した場合(すなわち入力したログインIDとパスワードがシステムに登録されている)、LoadIdentityを呼び出す。
- LoadIdentityメソッドで得たユーザー情報を認証済情報保存装置に保存する。
- VerifyCredentialメソッドがfalseを返した場合現在保持しているログイン情報を破棄する。

上記Authenticate処理を変更する場合、あるいはAuthenticate()内部でデータベース処理を共用するなどの場合Authenticateメソッドをオーバーライドする。

LoadUserメソッド内にはユーザー情報取得処理を記述する。

VerifyCredentialメソッド内にはログインID,パスワードの正当性検査をPasswordHashクラスを使用して記述する。

Authenticateをオーバーライドする場合、認証が成功した時にユーザー情報を認証済情報保存装置に保存する。ここでパスワード情報を保存してはならない。

#### 設定の変更

providerClassを作成したクラス情報に変更する。

### 新しいデータ認証済情報保存装置クラスの作成(C#)

#### クラス定義

CFW.Auth.AuthStorageクラスを継承し、GetIdentity、IsAuthenticated、SaveIdentity、RemoveIdentityを実装する。

それぞれ 認証済みデータの取得(GetIdentity)、認証済みの判定(IsAuthenticated)、認証済みデータの保存(SaveIdentity)、認証済データの破棄(RemoveIdentity)

#### 設定の変更

storageClassを作成したクラス情報に変更する。