2013-04-23 34 views
6

Tôi đang tích hợp OpenID vào ứng dụng hiện có của mình với các nhà cung cấp LiveID và Google. Trên trang đăng nhập của tôi, ngoài các trường đăng nhập ban đầu, tôi đã thêm các nút 'Đăng nhập bằng Google' và 'Đăng nhập bằng Microsoft'.Xử lý xác thựcResult từ các nhà cung cấp khác nhau trong cùng một trang

tôi có thể đọc thành công dữ liệu AuthenticationResult cho cả các nhà cung cấp ở trên, nhưng đang thực hiện điều này theo cách sau đây ...

Đối với các nút đăng nhập mới Tôi crafted một URL trả về để phân biệt chúng về lợi nhuận của người dùng:

Protected Sub btn_google_Click(sender As Object, e As EventArgs) Handles btn_google.Click 
    Dim client As New GoogleOpenIdClient 
    Dim u As New System.Uri("http://www.mytest.com/login.aspx?action=signin&provider=google") 
    client.RequestAuthentication(New HttpContextWrapper(HttpContext.Current), u) 
End Sub 

Protected Sub btn_live_Click(sender As Object, e As EventArgs) Handles btn_live.Click 
    Dim client As New MicrosoftClient("xyz", "12345") 
    Dim u As New System.Uri("http://www.mytest.com/login.aspx?action=signin&provider=microsoft") 
    client.RequestAuthentication(New HttpContextWrapper(HttpContext.Current), u) 
End Sub 

Vì vậy, khi người dùng được chuyển hướng trở lại Login.aspx, tôi sau đó có kiểm tra sau đây để xử lý các chức năng đăng nhập:

If Not Page.IsPostBack Then 
    If Request.QueryString("action") IsNot Nothing AndAlso Request.QueryString("action").Trim = "signin" Then 
     If Request.QueryString("provider") IsNot Nothing AndAlso Request.QueryString("provider").Trim <> String.Empty Then 
      Select Case Request.QueryString("provider").Trim 
       Case "microsoft" 
        Dim client As New MicrosoftClient("xyz", "12345") 
        Dim u As New System.Uri("http://www.mytest.com/loginlive.aspx?action=signin&provider=microsoft") 
        Dim result As DotNetOpenAuth.AspNet.AuthenticationResult = client.VerifyAuthentication(New HttpContextWrapper(HttpContext.Current), u) 
        ' remainder of logic removed 
        ' ... 
       Case "google" 
        Dim client As New GoogleOpenIdClient 
        Dim result As DotNetOpenAuth.AspNet.AuthenticationResult = client.VerifyAuthentication(New HttpContextWrapper(HttpContext.Current)) 
        ' remainder of logic removed 
        ' ... 
      End Select 
     End 
    End 
End If 

Câu hỏi chính của tôi ở đây là, đây có phải là cách tốt để xử lý AuthenticationResults không? Hoặc, có cách nào tốt hơn/an toàn hơn/thông minh hơn để thực hiện tương tự không?

Trả lời

1

Cách tốt hơn là sử dụng mẫu Abstract Factory kết hợp với Mẫu lệnh. Mà có thể làm giảm mã hóa cứng và cũng có mã lỏng lẻo cùng, vì vậy bạn có thể mở rộng các chức năng trong tương lai cho mỗi nhà cung cấp xác thực. Tìm đoạn mã của từng bộ phận của các mã dưới đây

Abstract Class cho "Nhà cung cấp BaseAuthentication"

public abstract class BaseAuthenticationProvider 
{ 
    //abstract Methods that need to be invoked from the concrete class, this need to be decided based on the functionality you need to achieve. This function would be invoked using the command pattern. 
    // AuthorizeUser() : this method would be invoked to authorize the user from the provider 

    //AuthenticateUser() : this method would be invoked once the user is redirected from the provider site. 

    //abstract Properties that will hold the base information for the authentication provider, this need to be decided based on the functionality you need to achieve 
    //CustomerSecret 
    //CustomerConsumerKey 
} 

Sử dụng đoạn mã sau đây để thực hiện lớp bê tông cho Gooogle, Yahoo, Microsoft, vv

public class GoogleAuthentication : BaseAuthenticationProvider 
{ 
    public GoogleAuthentication() 
    { 
      //initialization 
    } 

    public void AuthorizeUser() 
    { 
      //code 
    } 

    public string CustomerSecret() 
    { 
      //code 
    } 

    public string CustomerConsumerKey() 
    { 
      //code 
    } 
} 

lớp Factory để tạo ra các đối tượng cụ thể, để ngăn chặn từ việc tạo trong lập trường của lớp nhà máy này thực hiện một hàm tạo riêng.

public class AuthenticationProviderFactory 
{ 
    private AuthenticationProviderFactory() 
    { 
    } 

    public static BaseAuthenticationProvider GetInstance(string Domain) 
    { 
      switch (Domain) 
      { 
       case "google": 
        return new GoogleAuthentication(); 
       case "yahoo": 
        return new YahooAuthentication(); 
      } 
     } 
} 

Login.aspx: có các nút cho mỗi người trong số các nhà cung cấp xác thực, thiết lập giá trị cho "CommandName" cho mỗi nút và liên kết tất cả các nút với cùng xử lý sự kiện

cho ví dụ btn_google.CommandName = "google"

Protected Sub AuthenticationProvider_Click(sender As Object, e As EventArgs) Handles btn_google.Click, btn_yahoo.Click 
    AuthenticationProviderFactory.GetInstance(((Button)sender).CommandName).AuthorizeUser(); 
End Sub 

Phương thức ủy quyền người dùng sẽ gọi trang web nhà cung cấp tương ứng để xác thực. Khi nhà cung cấp chuyển hướng người dùng đến URL trả về, hãy áp dụng cùng một mẫu trên sự kiện Page_Load và gọi phương thức Autheticate từ lớp trừu tượng.

+0

Cảm ơn bạn đã nhập. Tôi đánh giá cao điểm của bạn, nhưng có một số đặt chỗ, cụ thể là ... Tôi hy vọng có thể đăng nhập tự động vào hệ thống của tôi nếu họ đã đăng nhập qua Google với một liên kết như thế này 'www.mydomain.com/autologin. aspx? provider = Google' để tiết kiệm thời gian khi nhấn nút phụ trên trang đăng nhập thông thường. Cũng vì các giá trị chuỗi như ConsumerKey chỉ được sử dụng một lần, di chuyển chúng vào một lớp sẽ cần biên dịch lại mỗi khi chúng được cập nhật. Đó là thực hành tốt? Xin lỗi kỹ năng mã hóa của tôi chỉ là trung bình vì vậy tôi có thể đã bỏ lỡ một số điểm chính với cách tiếp cận của bạn. – EvilDr

+1

1. đăng nhập trực tiếp: bạn vẫn có thể đạt được điều này theo mẫu tôi đã nói ở trên. Sử dụng cùng một phương pháp được sử dụng trong nút đăng nhập. Sử dụng cùng một cách tải trang của autologin.aspx 2. Di chuyển Consumerkey vào mã: khóa người dùng có thể được lưu trong tệp cấu hình hoặc tài nguyên và bạn có thể giới thiệu trực tiếp mã đó vào mã của mình. Tôi hy vọng điều này sẽ trả lời truy vấn của bạn. –

+0

Tuyệt vời. Các bit tôi đang đấu tranh để xem là * tại sao * mã của bạn là tốt hơn so với cách tiếp cận của tôi. Một lần nữa đổ lỗi cho kinh nghiệm của tôi, chỉ cần một số con trỏ sẽ là tuyệt vời! – EvilDr

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