2017-03-02 241 views
7

遵循一個在線教程以使用OWIN使用基於令牌的身份驗證後,我設法讓我的測試應用程序根據硬編碼的用戶名/密碼進行身份驗證,如演示所做的那樣。Asp.Net WebApi OWIN身份驗證

但是,現在我想從我的web應用程序中使用我的模型。

正如演示所說,我的身份驗證是在這段代碼中進行的。

namespace UI 
{ 
    public class AuthorisationServerProvider : OAuthAuthorizationServerProvider 
    { 
     public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context) 
     { 
      context.Validated(); // Means I have validated the client. 
     } 

     public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context) 
     { 
      // Here we validate the user... 
      var identity = new ClaimsIdentity(context.Options.AuthenticationType); 
      if (context.UserName == "user" && context.Password == "password") 
      { 
       identity.AddClaim(new Claim(ClaimTypes.Role, "admin")); 
       identity.AddClaim(new Claim("username", "user")); 
       identity.AddClaim(new Claim(ClaimTypes.Name, "My Full Name")); 
       context.Validated(identity); 
      } 
      else 
      { 
       context.SetError("Invalid grant", "Username or password are incorrect"); 
       return; 
      } 
     } 

    } 
} 

我有一個WebAPI控制器,我從我的webapi控制器接收模型,並...不知道如何調用上面的代碼。目前,上面的代碼需要調用myurl/token - 這是在啓動代碼中定義的。

public class Startup 
    { 
     public void Configuration(IAppBuilder app) 
     { 
      // Enables cors origin requests. 
      app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll); 

      // Config OAuth authorisation server; 

      var myProvider = new AuthorisationServerProvider(); 
      OAuthAuthorizationServerOptions options = new OAuthAuthorizationServerOptions 
      { 
       AllowInsecureHttp = true, // Live version should use HTTPS... 
       TokenEndpointPath = new PathString("/token"), 
       AccessTokenExpireTimeSpan = TimeSpan.FromDays(1), 
       Provider = myProvider 
      }; 

      app.UseOAuthAuthorizationServer(options); 
      app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions()); 

      HttpConfiguration config = new HttpConfiguration(); 
      WebApiConfig.Register(config); 
     } 
    } 

所以,我猜我的webapi調用的url應該是/ token?所以,在我的UI我的(剔除視圖模型)的代碼,我嘗試這樣做:

Login() 
    { 
     var data = { 
      username : this.login.emailAddress(), 
      password : this.login.password(), 
      RememberMe: this.login.rememberMe(), 
      grant_type: "password" 
     } 

     return $.ajax({ 
      type: "POST", 
      data: data ? JSON.stringify(data) : null, 
      dataType: "json", 
      url: "/token", 
      contentType: "application/json" 
     }).done((reply) => { 
      alert("Done!"); 
     }); 

    } 

但是,我得到一個異常:

「error」: 「unsupported_grant_type」 

在「郵差」,我能夠認證硬編碼的用戶名/密碼。

enter image description here

但我不知道如何從我的UI線了我的API調用,進行身份驗證。

我希望我的API控制器(ASP.Net的WebAPI)上創建一個「登錄」方法,就像這樣:

[Route("login"), HttpPost, AllowAnonymous] 
public ReplyDto Login(LoginRequest login) 
{ 
    ReplyDto reply = _userService.Login(login.Email, login.Password); 
    return reply; 
} 

所以,我_userService檢查用戶是否在數據庫中...如果是這樣,請在這裏調用我的OAuth身份驗證傳遞幾個參數。但不知道這是可能的。我可以從這個API方法調用我的身份驗證嗎?我需要刪除/令牌位。

回答

7

你不需要創建一個Login方法,因爲你已經擁有了它。這是http://localhost:1234/token。如果用戶存在並且密碼正確,這將生成一個令牌。但得到這個行爲,你需要從OAuthAuthorizationServerProvider

public class DOAuthServerProvider : OAuthAuthorizationServerProvider 

派生來實現自己的AuthServerProvider,然後你會覆蓋的方法來實現你的邏輯:

public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context) 
    { 

     try 
     { 
      string allowedOrigin = context.OwinContext.Get<string>(DOAuthStatic.ALLOWED_CORS_ORIGINS_KEY); 

      if (allowedOrigin != null) 
      { 
       context.OwinContext.Response.Headers[DOAuthStatic.CORS_HEADER] = allowedOrigin; 
      } 

      DAuthenticationResponse authResponse = await _authRepository.Authenticate(context.UserName, context.Password); 

      if (!authResponse.IsAuthenticated) 
      { 
       context.SetError(OAuthError.InvalidGrant, $"{(int)authResponse.AuthenticateResult}:{authResponse.AuthenticateResult}"); 

       return; 
      } 

      if (authResponse.User.ChangePasswordOnLogin) 
      { 
       _userAuthenticationProvider.GeneratePasswordResetToken(authResponse.User); 
      } 

      IDictionary<string, string> props = new Dictionary<string, string> 
      { 
       { 
        DOAuthStatic.CLIENT_NAME_KEY, context.ClientId ?? string.Empty 
       } 
      }; 

      ValidateContext(context, authResponse, props); 
     } 
     catch (Exception ex) 
     { 
      DLogOAuth.LogException(ex, "DCO0407E", "OAuthServerProvider - Error validating user"); 

      throw; 
     } 
    } 

你就要成功了,你就需要再執行兩個步驟:

  1. 在您的方法或控制器上添加AuthorizeAttribute以限制訪問未經認證的用戶。
  2. 添加您請求標頭的訪問令牌。如果你跳過這一步,你應該得到一個401 HTTP狀態碼,意味着未經授權。這是您可以確認您在第一步中添加的授權屬性的工作方式。

這裏是一個偉大的系列教程,說明一切都非常好:Token based authentication(路比我更好:))

1

修改內容類型「應用/ JSON的」到 「應用程序/ www-form-urlencoded「

您是Postman」application/www-form-urlencoded「格式的發送數據。但是在你的代碼中使用「application/Json」內容類型不匹配。所以,數據不能發送適當的格式。

如果工作正常,您可以更改。