Processing AuthenticationResult's from different providers in the same page - asp.net

I'm integrating OpenID to my existing application with LiveID and Google providers. On my login page, in addition to the original login fields I have added 'Log in with Google' and 'Log in with Microsoft' buttons.
I can successfully read the AuthenticationResult data for both providers above, but am accomplishing this in the following manner...
For the new login buttons I crafted a return URL to differentiate them on the user's return:
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
So when the user gets redirected back to login.aspx, I then have the following checks to process the login functionality:
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
My main question here is, is this a good way to process AuthenticationResults? Or, is there a better/more secure/more clever way to accomplish the same?

Better way would be to use Abstract Factory pattern in combination with Command Pattern. Which can reduce the hard coding and also have the code loosely coupled, so you can extend the functionality in future for each of the authentication provider. Find the snippet of each section of the code below
Abstract Class for "BaseAuthentication Provider"
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
}
Use the following code snippet to implement concrete class for the Gooogle, Yahoo, Microsoft etc.
public class GoogleAuthentication : BaseAuthenticationProvider
{
public GoogleAuthentication()
{
//initialization
}
public void AuthorizeUser()
{
//code
}
public string CustomerSecret()
{
//code
}
public string CustomerConsumerKey()
{
//code
}
}
Factory class to create the concrete object, to prevent from creating instance of this factory class implement a private constructor.
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 : have buttons for each of the authentication provider, set the value for "CommandName" for each of the button and link all the buttons to the same event handler
for e.g. 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
Respective AuthorizeUser method would call the respective provider site for authentication. When provider redirects the user to the return URL, apply the same pattern on the Page_Load event and call the Autheticate Method from the abstract class.

Related

Can I use System.Web.UI.Page in console application?

I want to test a function which is in a web page. Do I have way to use System.Web.UI.Page in a console application and put something in Session and test this way?
I created a test class and to inherit the Page but I could not put Session in it. When I type "myPage." as show below, I do not see anything come out after "."
<TestClass()> Public Class UnitTest2
Inherits System.Web.UI.Page
Dim myPage = New System.Web.UI.Page
myPage.
End Class
Please help!
Update: Below code seemed to pass the compiler
<TestClass()> Public Class UnitTest2
<TestMethod()>
Public Sub TestCheckRules()
Dim myPage As testWebPage = New testWebPage
myPage.testSession()
End Sub
End Class
Public Class testWebPage
Inherits System.Web.UI.Page
Public Sub New()
End Sub
Public Sub testSession()
Dim firstName As String = "John"
Dim lastName As String = "Smith"
Dim city As String = "Seattle"
Session("FirstName") = firstName
Session("LastName") = lastName
Session("City") = city
End Sub
End Class
Then when I ran I got the following error:
An exception of type 'System.Web.HttpException' occurred in System.Web.dll but was not handled in user code
Additional information: Session state can only be used when enableSessionState is set to true, either in a configuration file or in the Page directive. Please also make sure that System.Web.SessionStateModule or a custom session state module is included in the \\ section in the application configuration.

Calling ClientScript in Ajax method withhout a button is clicked in ASP.NET page

I need to call a function when an Ajax page method function returns success and without button click as protected sub. I couldn't include the ClientScript directly in the method or in shared function and the Method doesn't allow calling Public Sub UpdateText() without Shared ... any ideas?
'''' Method for Ajax with SQL and other functions
'''' ----------------------------------------------------------
<WebMethod()> _
Public Shared Function SendOrder(ByVal fulldata As String,
_ByVal id As Integer) As String
Try
UpdateText()
Return "Success"
Catch ex As Exception
Return "failure"
End Try
End Function
And here is the function I need to call
'''' Function to call only on success
'''' ----------------------------------------------------------
Public Sub UpdateText()
Dim jsUpdate As String
Dim cstype As Type
Dim cs As ClientScriptManager = Page.ClientScript
Dim jsUpdateTxt As String = "<script language='javascript'>...</script>"
ClientScript.RegisterStartupScript(cstype, jsUpdate, jsUpdateTxt)
End Sub
Page method calls have to be static.They cannot interact with the instance properties and methods of your Page class, because a page method call creates no instance of the Page or any of its controls.
after return either Success or failure, you can coding ajax methods in the client side like that
PageMethods.SendOrder(fulldata,id,OnRequestComplete, OnError);
function OnRequestComplete(result) {
//ToDo
}
function OnError(result) {
//ToDo
}

class modules in asp.net file system website

I have a class module in my App_code folder.
Private _connection As MySqlConnection
Private _connStr As String
Public Function Connect(dbName As String) As Boolean
Try
_connStr = "Database=" & dbName & ";" & _
"Data Source=192.16.0.1;" & _
"User Id=user;Password=pass"
_connection = New MySqlConnection(_connStr)
_connection.Open()
_connection.Close()
Return True
Catch ex As Exception
_connection = Nothing
Return False
End Try
Return False
End Function
I usually program in webform apps. Why can't I access this function from my aspx code behind pages? I added the import statement for the class. If i make that function shared I cant have those private variables.
I call the function in my aspx lik so;
If Connect(dbName) then....
That gets me an error "non shared member requires an object reference"
You need to add the keyword "Shared" to the method signature, like so:
Private Shared _connection As MySqlConnection
Private Shared _connStr As String
Public Shared Function Connect(dbName As String) As Boolean
This is because otherwise you have instance class members, not static members. The compiler error message is quite self-explanatory.
if you look at this example works:
Public Shared Function example123(ByVal USER As Integer, ByVal Section As String, ByVal ACTION As String) As Boolean
you assign a function shared so you can see it from outside the class
I hope you work

ASP.net: singleton class, instantiate just once per request?

I have a class called UserContext that tracks the activities of a given user on my website. It should be a singleton class (just one instance per user). In a Windows Forms application, I'd could write something like this:
Class UserContext
Public Shared Current As New UserContext()
Private Sub New(appName As String)
[...]
End Class
But on an ASP.net app, this would get shared across all current users.
If this class were only being used within a Page entity I could just store the UserContext instance in a Page variable—it doesn't necessarily need to survive postbacks. But other entities (that don't know about Page) also call UserContext, and I'd like them all to be given the same instance.
What can I do to ensure that a class is only instantiated once per http request (or per user)? Could I use the cache for this?
Public Shared Function GetContext() As UserContext
If HttpContext.Current.Cache("CurrentUserContext") Is Nothing Then HttpContext.Current.Cache("CurrentUserContext") = New UserContext()
Return HttpContext.Current.Cache("CurrentUserContext")
End Function
Might session state be a better option?
Cache and session state both survive postbacks—is there another option that resets with each new request?
Thanks for your help!
HttpContext.Current.Cache will be shared among all users. HttpContext.Current.Session is per user but persists for subsequent requests.
You need HttpContext.Current.Items:
Public Shared Function GetContext() As UserContext
If HttpContext.Current.Items("CurrentUserContext") Is Nothing Then HttpContext.Current.Items("CurrentUserContext") = New UserContext()
Return HttpContext.Current.Items("CurrentUserContext")
End Function
This will ensure a safe per request and per user cache store.
You can use the HttpContext.Current.Items collection.
You will need a locking strategy to handle concurrent requests if you are storing the variable for longer than the life of the request. Always assign on your read, and employ double-checked locking to enforce singleton.
Private ReadOnly lockObj As New Object()
Private Const CurrentUserContextKey As String = "CurrentUserContext"
Public Function GetContext() As UserContext
Dim session = HttpContext.Current.Session
Dim userContext = TryCast(session(CurrentUserContextKey), UserContext)
If userContext Is Nothing Then
SyncLock lockObj
userContext = TryCast(session(CurrentUserContextKey), UserContext)
If userContext Is Nothing Then
userContext = New UserContext()
session(CurrentUserContextKey) = userContext
End If
End SyncLock
End If
Return userContext
End Function

ASP.NET: Unfamiliar with Interfaces

I'm building a decent sized application in ASP.NET/VB.NET with various objects... I've never used interfaces before, and a fellow programmer balked when I mentioned this to him. Can anyone give me a quick overview on how they're used, what they're used for, and why I would use them? Maybe I don't need to use them for this project, but if they would help, I surely would love to try.
Thanks so much!
Once you "get" interfaces, OOP really falls into place. To put it simply, an interface defines a set of public method signatures, you create a class which implements those methods. This allows you generalize functions for any class which implements a particular interface (i.e. classes which have the same methods), even if those classes don't necessarily descend from one another.
Module Module1
Interface ILifeform
ReadOnly Property Name() As String
Sub Speak()
Sub Eat()
End Interface
Class Dog
Implements ILifeform
Public ReadOnly Property Name() As String Implements ILifeform.Name
Get
Return "Doggy!"
End Get
End Property
Public Sub Speak() Implements ILifeform.Speak
Console.WriteLine("Woof!")
End Sub
Public Sub Eat() Implements ILifeform.Eat
Console.WriteLine("Yum, doggy biscuits!")
End Sub
End Class
Class Ninja
Implements ILifeform
Public ReadOnly Property Name() As String Implements ILifeform.Name
Get
Return "Ninja!!"
End Get
End Property
Public Sub Speak() Implements ILifeform.Speak
Console.WriteLine("Ninjas are silent, deadly killers")
End Sub
Public Sub Eat() Implements ILifeform.Eat
Console.WriteLine("Ninjas don't eat, they wail on guitars and kick ass")
End Sub
End Class
Class Monkey
Implements ILifeform
Public ReadOnly Property Name() As String Implements ILifeform.Name
Get
Return "Monkey!!!"
End Get
End Property
Public Sub Speak() Implements ILifeform.Speak
Console.WriteLine("Ook ook")
End Sub
Public Sub Eat() Implements ILifeform.Eat
Console.WriteLine("Bananas!")
End Sub
End Class
Sub Main()
Dim lifeforms As ILifeform() = New ILifeform() {New Dog(), New Ninja(), New Monkey()}
For Each x As ILifeform In lifeforms
HandleLifeform(x)
Next
Console.ReadKey(True)
End Sub
Sub HandleLifeform(ByVal x As ILifeform)
Console.WriteLine("Handling lifeform '{0}'", x.Name)
x.Speak()
x.Eat()
Console.WriteLine()
End Sub
End Module
None of the classes above descend from one another, but my HandleLifeform method is generalized to operate on all of them -- or really any class which implements the ILifeform interface.
Since the basics have already been covered, lets move on to practical examples.
Say I'm going to have a Dictionary that stores String keys and Person objects and I'm going to pass this dictionary (actually, the reference to it) to some methods I have.
Now, my receiving method would look something like
Imports System.Collections.Generic
Public Sub DoSomething(ByVal myDict As Dictionary(Of String, Person))
' Do something with myDict here
End Sub
right?
But what if someone invents some new high performance dictionary class? I have to turn around and change every reference to Dictionary to FastDictionary!
However, if I had coded to the interface in the first place, I wouldn't have this problem:
Imports System.Collections.Generic
Public Sub DoSomething(ByVal myDict As IDictionary(Of String, Person))
' Do something with myDict here
End Sub
Now it takes any dictionary!
Interfaces basically allow you to define a type's contract without specifying its implementation.
The idea is that if you know that a given type implements a certain interface it is guaranteeing that certain methods and properties are members of that type.
So any type that implements the following interface:
Interface ISpinnable
Sub Spin()
End Interface
Would have to implement the Spin method. But the caller of this type that implements ISpinnable does not care about how it is implemented, it just cares that the method is there. Here is a type that implements ISpinnable:
Class Top Implements ISpinnable
Sub Spin()
' do spinning stuff
End Sub
End Class
The benefit to this is that you can create method arguments of type ISpinner and allow the caller of these methods to pass any type to you as long as it implements the interface. Your method is no longer tightly coupled to the concrete type that the caller is using.
An interface is a contract without an implementation. It allows you to define what a type will look like without indicating what the implementation of that type is.
This allows you to have various implementations of an interface, which would suit your particular needs.
A good example is the IComparer(Of T) interface. You can have one implementation that will compare two items based on which is greater, and then another which will return a value based on which is lesser.
Then, you could pass one or the other to the static Sort method on the Array class to sort your items in ascending, or descending order, respectively.
One of the things interfaces can be useful is browsing through the array of objects of different types but which share the same interface.
Can't say for VB, but in C# you can use the handy "is" operator to determine if object's type implements the given interface and it's safe to access methods of that interface by casting. Sorry for C#, but i'll try to put some comments in =))
//we declare 3 different interfaces each requiring to implement one method
interface IProgrammer
{
void WriteCode();
}
interface ITester
{
void FindBugs();
}
interface IWorker
{
void StartShift();
}
// each programmer will be able to start his shift and write code
class Programmer : IWorker, IProgrammer
{
public void StartShift()
{
// ...
}
public void WriteCode()
{
// ...
}
}
// each tester will be able to start his shift and find bugs
class Tester : IWorker, ITester
{
public void StartShift()
{
// ...
}
public void FindBugs()
{
// ...
}
}
//then in code you can rely on objects implementing the interface to
// be able to do tasks interface requires to do
static void Main()
{
IWorker[] workers = new IWorker[3];
workers[0] = new Programmer();
workers[1] = new Tester();
workers[2] = new Tester();
// now we can browse through array of different workers because they all share
// the IWorker interface
foreach(IWorker worker in workers)
{
// All IWorkers can StartShift so we access its methods without casts
worker.StartShift();
if(worker is IProgrammer)
{
// Since that worker also implements IProgrammer
// we cast worker as IProgrammer and access IProgrammer method(s)
(worker as IProgrammer).WriteCode();
}
if(worker is ITester)
{
// Same,
// we cast worker as ITester and access ITester method(s)
// handy! =)
(worker as ITester).FindBugs();
}
}
A classic example is the Data Layer where you use it to support multiple database format. This was actually very useful before ORMappers came into the picture in mainstream programming.
Your interface just tells what type of method and properties your object has, the object itself then has to implement these methods.
IMyDatabase myDb;
switch case myDbFormat {
case "mysql":
myDb = new MyDbMySql();
break;
case "mssql" :
myDb = new MyDbMsSql();
break;
}
myDb.SaveToDatabase(some data)
Ofcourse the myDb classes have to implement the ImyDatabase Interface. I assume you can see how useful this is :).

Resources