2017-03-02 20 views
7

Sau khi làm theo hướng dẫn trực tuyến để sử dụng xác thực dựa trên mã thông báo bằng OWIN, tôi đã quản lý ứng dụng thử nghiệm của mình xác thực với tên người dùng/mật khẩu được mã hóa cứng, như bản demo đã làm.Asp.Net WebApi OWIN Xác thực

Tuy nhiên, bây giờ tôi muốn mô hình của mình từ ứng dụng web của tôi được sử dụng.

Xác thực của tôi xảy ra, như bản demo đã nói, trong bit mã này.

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; 
      } 
     } 

    } 
} 

Tôi có bộ điều khiển WebAPI, tôi nhận mô hình từ và ... không chắc chắn cách gọi mã trên, từ bộ điều khiển webapi của tôi. Tại thời điểm này, mã ở trên dự kiến ​​một cuộc gọi đến myurl/token - được xác định trong mã khởi động.

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); 
     } 
    } 

Vì vậy, tôi đoán url từ cuộc gọi webapi của tôi phải là/mã thông báo? Vì vậy, trong tôi (Knockout Xem mô hình) mã trên giao diện người dùng của tôi, tôi đã cố gắng này:

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!"); 
     }); 

    } 

Nhưng, tôi nhận được một ngoại lệ:

“error”: “unsupported_grant_type” 

Trong 'Postman', tôi có thể xác thực tên người dùng/mật khẩu được mã hóa cứng.

enter image description here

Nhưng tôi không chắc chắn làm thế nào để dây lên gọi api của tôi từ giao diện người dùng của tôi, để xác thực.

Tôi đã hy vọng để tạo ra một phương pháp 'Đăng nhập' trên bộ điều khiển api của tôi (ASP.Net WebAPI), như thế này:

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

Vì vậy, kiểm tra _userService của tôi nếu người dùng là trong cơ sở dữ liệu ... nếu có, hãy gọi xác thực OAuth của tôi tại đây bằng một vài thông số. Nhưng không chắc điều đó là có thể. Tôi có thể gọi xác thực của mình từ phương thức api này không? Tôi cần phải loại bỏ các bit/bit mặc dù.

Trả lời

7

Bạn không cần phải tạo phương thức Đăng nhập vì bạn đã có nó. Đó là http://localhost:1234/token. Điều này sẽ tạo ra một mã thông báo nếu người dùng tồn tại và nếu mật khẩu là chính xác. Nhưng nhận được hành vi này, bạn cần phải thực hiện AuthServerProvider của riêng bạn bằng cách bắt nguồn từ OAuthAuthorizationServerProvider

public class DOAuthServerProvider : OAuthAuthorizationServerProvider 

và sau đó bạn sẽ ghi đè lên một phương pháp để thực hiện logic của bạn:

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; 
     } 
    } 

Bạn đang ở gần đó, bạn chỉ cần cần thực hiện thêm hai bước:

  1. Thêm AuthorizeAttribute vào phương pháp hoặc bộ điều khiển để hạn chế quyền truy cập cho người dùng chưa được xác thực.
  2. Thêm mã thông báo truy cập mà bạn yêu cầu tiêu đề. Nếu bạn bỏ qua bước này, bạn sẽ nhận được mã trạng thái HTTP 401, có nghĩa là trái phép. Đây là cách bạn có thể xác nhận rằng thuộc tính ủy quyền mà bạn đã thêm trong bước một hoạt động.

Dưới đây là một loạt lớn các hướng dẫn giải thích tất cả mọi thứ thực sự tốt: Token based authentication (cách tốt hơn tôi có :))

1

Thay đổi nội dung Loại "application/json" để ứng dụng "/ www-form-urlencoded "

Bạn đang gửi dữ liệu ở định dạng" ứng dụng/www-form-urlencoded ". Nhưng trong Mã của bạn Sử dụng "application/Json" Loại Nội dung Không khớp. Vì vậy, dữ liệu không gửi đúng định dạng.

Bạn có thể thay đổi Nếu nó hoạt động tốt.

Các vấn đề liên quan