2014-12-02 32 views
0

我想實現基於web api 2的基於聲明的oauth令牌認證。爲此,我已經創建OWIN承載認證失敗的web api 2

[assembly: OwinStartup(typeof(PMW.Api.Startup))] 
    public class Startup 
    { 
     //private IUnitOfWork _unitOfWork; 
     //private IUserService _userService; 
     //private ICommonService _commonService; 

     public void Configuration(IAppBuilder app) 
     { 
      HttpConfiguration config = new HttpConfiguration(); 
      WebApiConfig.Register(config); 
      app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll); 
      app.UseWebApi(config); 

      IUnityContainer container = GetUnityContainer(); 
      config.DependencyResolver = new UnityDependancyResolver(container); 

      //_unitOfWork = container.Resolve<IUnitOfWork>(); 
      //_userService = container.Resolve<IUserService>(); 
      //_commonService = container.Resolve<ICommonService>(); 

      MapAutomapper(); 

      ConfigureOAuth(app); 

      //var OAuthBearerOptions = new OAuthBearerAuthenticationOptions() 
      //{ 
      // Provider = new QueryStringOAuthBearerProvider(), 
      // AccessTokenProvider = new AuthenticationTokenProvider() 
      // { 
      //  OnCreate = create, 
      //  OnReceive = receive 
      // }, 
      //}; 

      //app.UseOAuthBearerAuthentication(OAuthBearerOptions); 

     } 

     public static Action<AuthenticationTokenCreateContext> create = new Action<AuthenticationTokenCreateContext>(c => 
     { 
      c.SetToken(c.SerializeTicket()); 
     }); 

     public static Action<AuthenticationTokenReceiveContext> receive = new Action<AuthenticationTokenReceiveContext>(c => 
     { 
      c.DeserializeTicket(c.Token); 
      c.OwinContext.Environment["Properties"] = c.Ticket.Properties; 
     }); 

     private void MapAutomapper() 
     { 
      //Mapper code 
     } 


     private IUnityContainer GetUnityContainer() 
     { 
      //Create UnityContainer   
      IUnityContainer container = //unity mapping 

      return container; 
     } 

     public void ConfigureOAuth(IAppBuilder app) 
     { 
      OAuthAuthorizationServerOptions OAuthServerOptions = new OAuthAuthorizationServerOptions() 
      { 
       AllowInsecureHttp = true, 
       TokenEndpointPath = new PathString("/token"), 
       AccessTokenExpireTimeSpan = TimeSpan.FromDays(1), 
       Provider = new SimpleAuthorizationServerProvider() 
      }; 

      // Token Generation 
      app.UseOAuthAuthorizationServer(OAuthServerOptions); 
      app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions()); 

     } 


    } 

和授權類被定義爲下面

public class SimpleAuthorizationServerProvider : OAuthAuthorizationServerProvider 
    { 
     public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context) 
     { 
      context.Validated(); 
     } 

     public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context) 
     { 
      IUnityContainer container = //unity code for mapping login related service 



      var _commonService=container.Resolve<ICommonService>() ; 
      var password =// Encrypt password 



      UserService _userService = new UserService(container.Resolve<IUnitOfWork>(), 
       container.Resolve<IUserMasterRepository>(), container.Resolve<IUserDetailRepository>()); 
      var userToPass = new UserDTO() 
      { 
       EmailId = context.UserName, 
       Password = password 
      }; 

      var user = _userService.AuthenticateUser(userToPass); 


      if (!user.Succeeded) 
      { 
       context.SetError("invalid_grant", "The user name or password is incorrect."); 
       return; 
      } 

      var identity = new ClaimsIdentity(context.Options.AuthenticationType); 
      identity.AddClaim(new Claim(ClaimTypes.Name, context.UserName)); 
      identity.AddClaim(new Claim(ClaimTypes.Role, "user")); 

      context.Validated(identity); 



     } 
    } 

該代碼被適當地工作,併產生令牌的客戶端應用程序。但是,如果我使用Authrize屬性如下所示。它總是失敗,錯誤401未經授權。

[Authorize] 
     [HttpGet] 
     public UserDTO Test() 
     { 
      return new UserDTO(); 
     } 

以下是請求和失敗方法詳細信息的快照。 enter image description here

請讓我們知道我缺少什麼才能正確實施授權流程。

+0

你能說明你如何從測試方法中獲取GET?我的意思是,正在發送:授權:承載者作爲請求標頭正確嗎? – 2014-12-02 16:24:35

+0

我已經添加了包含授權承載令牌的請求部分引用的快照。 – parth1729 2014-12-03 09:03:00

+0

從快照中的信息看來,您似乎有兩個項目:一個用於授權,另一個用於資源。你有沒有在兩個webconfig文件中檢查machinekey是否相同?檢查這個問題:http://stackoverflow.com/questions/25901414/owin-authentication-between-mvc-5-and-web-api-separate-iis-applications/25942811#25942811 – 2014-12-03 10:16:13

回答

0

也許是CORS問題;嘗試在GrantResourceOwnerCredentials方法中添加這些行:

public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context) 
{ 
    var allowedOrigin = context.OwinContext.Get<string>("as:clientAllowedOrigin"); 

    if (allowedOrigin == null) allowedOrigin = "*"; 

    context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] {allowedOrigin}); 

    ... 
}