ASP.NET   IDENTITY   Token based authentication   Web Api 
▌背景
當完成了OWIN Identity的Authentication Server後,我們已可認證並取得Token。
下一步當然是利用加入Token認證機制到其他的Http
Restful Service。
如此在SOA或SP的架構下,可降低Authentication server和Resource serer的耦合性。
PS. 在實作本篇程式碼之前,必須先建立一個Identity Authentication Service。 可參考相關文章建立。
▌相關文章
▌環境
l   Visual Studio 2015
l   WEB API 2.2
l   Entity Framework 6
▌實作
▋Packages we need
先安裝相關套件:
Microsoft.OWIN.Host.SystemWeb
MIcrosoft.AspNet.Identity.Owin
Microsoft.Owin.Security.OAuth
Microsoft.Owin.Security
Microsoft.AspNet.WebApi.Cors
▋OWIN Startup.cs
先移除預設WebApi的Register方法,
l   Global.asax
| 
protected void
  Application_Start() 
{ 
            AreaRegistration.RegisterAllAreas(); 
            //GlobalConfiguration.Configure(WebApiConfig.Register); 
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); 
            RouteConfig.RegisterRoutes(RouteTable.Routes); 
            BundleConfig.RegisterBundles(BundleTable.Bundles); 
} | 
l   OWIN Startup
| 
public partial class Startup 
    { 
        public void Configuration(IAppBuilder appBuilder) 
        { 
            HttpConfiguration config = new HttpConfiguration(); 
            //Configure OAuth 
            this.configureOAuth(appBuilder); 
            //Configure WebApi 
            this.configureWebApi(appBuilder); 
        } 
        private void configureOAuth(IAppBuilder app) 
        { 
            app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions 
            { 
            }); 
        } 
        private void configureWebApi(IAppBuilder app) 
        { 
            var config = new HttpConfiguration(); 
            //
  Configure Web API to use only bearer token authentication. 
          config.SuppressDefaultHostAuthentication(); 
          config.Filters.Add( 
                new HostAuthenticationFilter(OAuthDefaults.AuthenticationType)); 
            // Web API routes 
            config.MapHttpAttributeRoutes(); 
            config.Routes.MapHttpRoute( 
                name: "DefaultApi", 
                routeTemplate: "api/{controller}/{action}/{id}", 
                defaults: new { id = RouteParameter.Optional } 
            ); 
            //Enable CORS 
            config.EnableCors(); 
            app.UseWebApi(config); 
        } 
    } | 
▋Securing Http
Restful Service
最後,只要在我們的WebApi Http方法上加上 [Authorize] ,表示此方法需要經過認證的Request才可使用。
| 
[Authorize] 
[HttpGet] 
public IEnumerable<string> Get() 
{   
return new string[] { "The website is protected by
  an authentication server. @2015" }; 
} | 
▌測試
▋Testing in IIS
Express
環境為:
Authentication
Service is on http://localhost:7531
Resource
Service (Web Api) is on http://localhost:3241
如下圖,先取得token後,在第一次送出Get並無夾帶token,因此回應為401。
夾帶token後再次request,認證成功可取得資源。
▋Testing in
physical IIS at different servers
接下來,我嘗試將Authentication Server和Resource Server分開到兩台不同的機器;
將DB Connection和URL調整後,重新做一次測試。
備註:
| 
在佈署後,送出要求token時出現 401的錯誤。 
確認Http及DB連線及防火牆都沒有問題的情況下,偶然在Authentication Service的Application Start加入查詢資料庫的程式碼;
   
重啟Authentication Service後,再次送出Request給它,此時正常取得資料庫資料,並且Authentication
  Service的授權功能恢復正常,可正常取得token。 
我猜想可能的原因在於使用EF Code first的情況下,必須由第一次作動EF來建立AP和DB之間的連線,否則Authentication Server會一直回傳401。  | 
| 
<system.web> 
    <compilation debug="true" targetFramework="4.5.2" /> 
    <httpRuntime targetFramework="4.5.2" /> 
    <!--<authentication
  mode="None" />--> 
    <machineKey validationKey="…" 
decryptionKey="…" 
validation="SHA1" decryption="AES"/> 
</system.web> | 
測試結果如下,我是把Web Api (Resource Server)放在localhost, Authentication Server放在另一台開發機器。
▌Reference



 
沒有留言:
張貼留言