[VB.NET] REST API⑭ OAuth2.0 認証#1(APIに認証機能を実装)
ASP.NET MVC ビューに複数のパラメーターを渡すで作成したサンプルを改造して、
Web APIにOAuth2.0認証の機能を実装してみましょう。
※ VisualStudio2019
※ 当方のOAuth認証の知識が不足しているため、あくまで参考程度にとどめてください。
パッケージのインストール
まずはNugetから、必要なパッケージをインストールしていきます。
インストールするのは以下の4つのOwin関連のパッケージです。
Microsoft.Owin.Host.SystemWeb
Microsoft.Owin.Security.OAuth
Microsoft.AspNet.WebApi.Owin
Microsoft.AspNet.Identity.Owin
Owinというのは、「Open Web Interface for .NET」の略で、「HTTPを処理するサーバとアプリケーションを抽象化するためのインターフェイスの仕様」らしいです。
正直いまいちピンきていませんが、とりあえず動くサンプルを作っていきます。
「ツール」>「Nugetパッケージマネージャー」>「ソリューションのNugetパッケージの管理」をクリックします。
パッケージの管理画面が開いたら、「参照」タブを選択して、検索ワードに「Owin」と入力します。
すると、関連するパッケージが表示されます。
まずは、「Microsoft.Owin.Host.SystemWeb」をインストールします。
パッケージを選択して、インストールしたい「プロジェクト」にチェックを付けて「インストール」をクリックすればOKです。インストール中に「変更のプレビュー」とか「ライセンスへの同意」のメッセージが表示されたら、「OK」とか「同意」を押してください。
続けて「Microsoft.Owin.Security.OAuth」もインストールします。
続けて「Microsoft.Owin.Host.SystemWeb」もインストールします。
続けて「Microsoft.AspNet.Identity.Owin」もインストールします。
インストールするものはこれで終わりです。
次はいよいよ実装をしていきます。
WebApiConfig に認証方法を追加する
ソリューションエクスプローラで、 「App_Start」>「WebApiConfig.vb」を開き、「Bearer Token」認証のみを使用するようにコードを追加します。
コード
Imports System
Imports System.Collections.Generic
Imports System.Linq
Imports System.Web.Http
Public Module WebApiConfig
Public Sub Register(ByVal config As HttpConfiguration)
' Web API の設定およびサービス
'Bearer token 認証
config.SuppressDefaultHostAuthentication()
config.Filters.Add(New HostAuthenticationFilter(Microsoft.Owin.Security.OAuth.OAuthDefaults.AuthenticationType))
' Web API ルート
config.MapHttpAttributeRoutes()
config.Routes.MapHttpRoute(
name:="DefaultApi",
routeTemplate:="api/{controller}/{id}",
defaults:=New With {.id = RouteParameter.Optional}
)
End Sub
End Module
OAuth認証のプロバイダーを追加
次に、OAuth認証をするためのプロバイダークラスを追加します。
注意点として、このサンプルではASP.NETフォルダーから「App_Code」フォルダを作って、その中にコードファイルを作成しています。
この方法だと、コードファイルのビルドアクションが「コンテンツ」で作成されるため、追加後に「ビルド」に変更する必要があります。この作業をしないと、追加したクラスを別のモジュールから参照できないので注意してください。
ソリューションエクスプローラでプロジェクトを右クリックし、
「追加」>「ASP.NETフォルダーの追加」>「App_Code」をクリックして、フォルダを追加します。
ソリューションエクスプローラで、 追加した「App_Code」を右クリックして、「追加」>「クラス」をクリックします。
クラス名を入力し、「追加」をクリックします。
このサンプルでは、「OAuthProvider」という名前にしています。
追加した「OAuthProvider」クラスのビルドアクションを変更します。
ソリューションエクスプローラーで、 「OAuthProvider」 を右クリックし、プロパティを表示します。
プロパティウィンドウで、「ビルドアクション」を「コンパイル」に変更します。
「OAuthProvider」 にカスタム認証機能を実装します。
「OAuthAuthorizationServerProvider」を継承し、メソッドをオーバーライドします。
「GrantResourceOwnerCredentials」では、ユーザーとパスワードの確認をしています。
このサンプルではコード内でユーザーとパスワードを固定でチェックしています。
ユーザーとパスワードが一致しない場合は要求を拒否します。
コード
Imports System.Security.Claims
Imports System.Threading.Tasks
Imports Microsoft.Owin.Security.OAuth
Public Class OAuthProvider
Inherits OAuthAuthorizationServerProvider
''' <summary>
''' クライアント有効チェック
''' </summary>
''' <param name="context"></param>
''' <returns></returns>
Public Overrides Function ValidateClientAuthentication(ByVal context As OAuthValidateClientAuthenticationContext) As Task
context.Validated()
Return Task.FromResult(0)
End Function
''' <summary>
''' ユーザー認証
''' </summary>
''' <param name="context"></param>
''' <returns></returns>
Public Overrides Function GrantResourceOwnerCredentials(ByVal context As OAuthGrantResourceOwnerCredentialsContext) As Task
'テスト用なのでユーザー/パスワードは固定
Dim user As String = "user1"
Dim pass As String = "password1"
'ユーザー/パスワードをチェック
If context.UserName = user AndAlso context.Password = pass Then
'identityを生成
Dim identity = New ClaimsIdentity(context.Options.AuthenticationType)
identity.AddClaims({New Claim(ClaimTypes.GivenName, context.UserName), New Claim(ClaimTypes.Role, "Admin")})
context.Validated(identity)
Else
'拒否する
context.Rejected()
End If
Return Task.FromResult(0)
End Function
End Class
OAuthのスタートアップを追加する
続いて、OAuthのスタートアップクラスを追加します。
ソリューションエクスプローラーで、プロジェクトを右クリックし、「追加」>「クラス」をクリックします。
クラス名を入力し、「追加」をクリックします。
このサンプルでは、「Startup」という名前にしています。
「Startup」にOAuthベアラートークンを使用するためのコードを記述します。
「/Token」にアクセスすることで「OAuthProvider」が呼び出され、アクセストークンが取得できるようになります。
「AccessTokenExpireTimeSpan」でアクセストークンの有効期限を1分にしているのは、有効期限切れの時の動作をテストしたかったためです。デフォルトは20分のようです。
コード
Imports Microsoft.Owin
Imports Microsoft.Owin.Security.OAuth
Imports Owin
<Assembly: OwinStartup(GetType(Startup))>
Public Class Startup
Public Sub Configuration(ByVal app As IAppBuilder)
app.UseOAuthBearerTokens(New OAuthAuthorizationServerOptions With {
.TokenEndpointPath = New PathString("/Token"),
.Provider = New OAuthProvider,
.AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(1),
.AllowInsecureHttp = True
})
End Sub
End Class
コントローラーに認証機能をつける
APIのコントローラー(ApiTestController)に、認証機能をつけます。
やり方は簡単で、
<Authorize>
Public Class ApiTestController
のように、クラスに「Authorize」属性をつけるだけです。
実行して確認する
さっそく実行してみましょう。実行方法はこちらを参照してください。
アドレスバーに「/ViewTest/index」と入力してEnterキーを押してページを移動してみてください。
ユーザー認証もトークンの取得もせずにリクエストしているので、エラーメッセージが表示されリクエストが拒否されるようになりました。
OAuth2.0認証の機能を実装 をAPIに実装してみました。
Microsoftのパッケージをインストールすれば楽に実装できるのが良いですね。ありがたいことです。
※繰り返しになりますが、ここで紹介したのはあくまでサンプルレベルのものですので注意してください。
難しいことはMicrosoftのパッケージがやってくれてるようですが、これで十分かどうかは恥ずかしながら私の知識では判断できません。
次回は、ビューからこのAPIに認証トークンのリクエストをおこなってみます。