2013-04-23 26 views
6

我正在使用LiveID和Google提供程序将OpenID集成到我现有的应用程序中。在我的登录页面上,除了我已添加的“登录Google”和“使用Microsoft登录”按钮的原始登录字段外。在同一页面中处理来自不同供应商的AuthenticationResult

我可以成功读取上面都提供商AuthenticationResult数据,但我通过以下方式实现这个...

新登录按钮,我精心设计了一个返回URL来区分它们对用户的回报:

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 

因此,当用户被重定向回到login.aspx的,然后我有以下检查来处理登录功能:

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 

我的主要问题在于,这是处理AuthenticationResults的好方法吗?或者,是否有更好/更安全/更聪明的方法来完成相同的目标?

回答

1

更好的方法是将抽象工厂模式与命令模式结合使用。这可以减少硬编码并使代码松散耦合,因此您可以为每个身份验证提供程序扩展功能。请看下面

抽象类的代码的每个部分的片段为“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 
} 

使用下面的代码片段来实现具体类的Gooogle企业,雅虎,微软等

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

    public void AuthorizeUser() 
    { 
      //code 
    } 

    public string CustomerSecret() 
    { 
      //code 
    } 

    public string CustomerConsumerKey() 
    { 
      //code 
    } 
} 

工厂类创建具体对象,从创建中,以防止这个工厂类的立场实现一个私有构造函数。

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:有按钮对每个认证提供的,对于“的CommandName”设置的值对于每个按钮的和所有的按钮链接到相同的事件处理程序

为例如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 

相应的AuthorizeUser方法会调用相应的提供者站点进行身份验证。当提供者将用户重定向到返回URL时,请在Page_Load事件中应用相同的模式,并从抽象类中调用Aututhate方法。

+0

感谢您的输入。我很欣赏你的观点,但有一些保留意见,即......我希望能够自动登录到我的系统,如果他们已经通过谷歌登录这样的链接,如www.mydomain.com/autologin。 aspx?provider = Google',以节省正常登录页面上额外按钮的时间。此外,因为像ConsumerKey这样的字符串值只能使用一次,所以将它们移动到类中时,每次更新时都需要重新编译。这是不错的做法吗?对不起,我的编程技能只有平均水平,所以我可能错过了一些关键点。 – EvilDr 2013-06-04 07:53:32

+1

1.直接登录:您仍然可以通过上述模式实现此目的。使用登录按钮中使用的相同方法。在自动登录的页面加载中使用相同的方法。aspx 2.将Consumerkey移动到代码中:消费者密钥可以保存在配置文件或资源文件中,您可以直接将它们引用到您的代码中。 我希望这会回答您的查询。 – 2013-06-04 09:52:55

+0

好吧。我努力看到的一点是*为什么*你的代码比我的方法更好。再次指责我的经验,只是一些指针会很棒! – EvilDr 2013-06-06 10:31:33

相关问题