New Posts New Posts RSS Feed: [Solved]Role based (Form) Authentication changes
  FAQ FAQ  Forum Search   Calendar   Register Register  Login Login

[Solved]Role based (Form) Authentication changes

 Post Reply Post Reply
Author
orcities View Drop Down
Senior Member
Senior Member
Avatar

Joined: 28-Aug-2007
Location: United States
Posts: 454
Post Options Post Options   Quote orcities Quote  Post ReplyReply Direct Link To This Post Topic: [Solved]Role based (Form) Authentication changes
    Posted: 20-Sep-2007 at 2:43pm
I was able to use role based authentication fairly easily on the last Cabana release. But, it seems that authentication has change from LoginClientCore to a Service.
 
I have created a login form. And need to verify the user. AppAuthentication does Windows authentication. I am trying to figure out how to pass my username and password to the AppAuthenticationService to validate the user.
 
I added another Authenticate(string username, string password). And in my form I attempt, not sure if it is correct, to get the AppAuthenticationService using :

[ServiceDependency]

public IAuthenticationService AuthenticationService { set { mAuthenticationService = value; } }

private IAuthenticationService mAuthenticationService;

But of course it doesn't get my implementation of the service. I see in the ShellApp.cs filwer where it creates the service. But I am probably unsuccessful in getting that service.

Can you guys help?


Edited by orcities - 24-Sep-2007 at 7:55am
Back to Top
Linguinut View Drop Down
Senior Member
Senior Member
Avatar

Joined: 14-Jun-2007
Location: United States
Posts: 394
Post Options Post Options   Quote Linguinut Quote  Post ReplyReply Direct Link To This Post Posted: 20-Sep-2007 at 5:29pm
Check out the LoginManager of the model project.  I had to implement the GetUserRoles method to get my authentication to work.
Back to Top
orcities View Drop Down
Senior Member
Senior Member
Avatar

Joined: 28-Aug-2007
Location: United States
Posts: 454
Post Options Post Options   Quote orcities Quote  Post ReplyReply Direct Link To This Post Posted: 20-Sep-2007 at 6:26pm
From what I understand from your previous thread; you are using Windows Authentication.
 
I am using form. I need to provide the input.
Back to Top
Bill Jensen View Drop Down
IdeaBlade
IdeaBlade
Avatar

Joined: 31-Jul-2007
Location: United States
Posts: 229
Post Options Post Options   Quote Bill Jensen Quote  Post ReplyReply Direct Link To This Post Posted: 20-Sep-2007 at 7:33pm
I'll respond to this tomorrow.
 
Bill J.
Back to Top
Linguinut View Drop Down
Senior Member
Senior Member
Avatar

Joined: 14-Jun-2007
Location: United States
Posts: 394
Post Options Post Options   Quote Linguinut Quote  Post ReplyReply Direct Link To This Post Posted: 21-Sep-2007 at 9:40am
Yes, I am using Windows Authentication, but the roles have to come from somewhere.  The GetUserRoles method is where you would do that.  I am guessing that your roles are stored in the database.  You would set up the script to retrieve the assigned roles as a string collection from your table for the user.  Not sure if this actually helps you (I hope it does), but I thought I'd throw my 2 cents in.  Btw, I don't think LoginManager is limited to Windows Authentication.
Back to Top
orcities View Drop Down
Senior Member
Senior Member
Avatar

Joined: 28-Aug-2007
Location: United States
Posts: 454
Post Options Post Options   Quote orcities Quote  Post ReplyReply Direct Link To This Post Posted: 21-Sep-2007 at 9:43am
I am using Forms so I have to be able to pass the UserName and Password to the AuthenticationService.
 
I can't figure out how to do that.
 
In the last version of Cabana it was handled in the LoginClientCore.
Back to Top
Bill Jensen View Drop Down
IdeaBlade
IdeaBlade
Avatar

Joined: 31-Jul-2007
Location: United States
Posts: 229
Post Options Post Options   Quote Bill Jensen Quote  Post ReplyReply Direct Link To This Post Posted: 21-Sep-2007 at 12:04pm
Yes, in this version of Cabana, Ward has factored client-side authentication into the AppAuthenticationService, implementing IAuthentication service.  It's in the Foundation project.
 
IAuthentication service exposes one method, Authenticate(), that is invoked at application startup.  This calls Login() to first get the user's credentials, then attempt to login via the persistence manager:
 

/// <summary>Login this manager.</summary>

protected virtual void Login(PersistenceManager pManager) {

ILoginCredential aCredential = GetCredential();

Login(pManager, aCredential);

}

 
In GetCredential() we see:
 

/// <summary>Get the credential for this user.</summary>

/// <remarks>

/// This implementation only knows how to get a Windows Credential;

/// see <see cref="GetWindowsCredential"/>.

/// </remarks>

protected virtual ILoginCredential GetCredential() {

ILoginCredential credential = GetWindowsCredential();

if (credential == null) {

// We don't have an alternative way to get the credential

throw new InvalidOperationException("Windows user is not authenticated.");

}

return credential;

}

It is here that you could write code to display a login form and create an object implementing the DevForce ILoginCredential interface.  The class IdeaBlade.Persistence.LoginCredential is the base implementation of this interface.

On the server side, the credentials are passed to the Login() method of the LoginManager (in the Model project).  There, the method GetAppIdentity() checks for a non-empty user name (an empty user name signals that Windows authentication should be used) and invokes GetUserPasswordIdentity():
 

/// <summary>

/// Get user based on user LoginName and password

/// </summary>

/// <param name="pCredential">Login credential.</param>

/// <param name="pManager">PersistenceManager for retrieving user.</param>

/// <returns>Identity built based on lookup of user's LoginName and password.</returns>

[DebuggerNonUserCode] // Let client catch exceptions

private static AppIdentity GetUserPasswordIdentity(ILoginCredential pCredential, PersistenceManager pManager) {

IUser aUser = SecurityUser.GetUserByCredential(pManager, pCredential);

return new AppIdentity(aUser.FullName, aUser.Id, "UserPassword");

}

Here we must supply an implementation of IUser from somewhere.  In Cabana (and wizard-based applications), we rely on the existence of an entity in the model called SecurityUser that has a static factory method GetUserByCredential().  In the Cabana implementation, this method retrieves the user from the database by username and password.  You can provide code that authenticates the user and returns an implementation of IUser.
 
Back in the Login(credential, pm) method of LoginManager, once the user is authenticated and we have an AppIdentity object, GetUserRoles() is invoked and a Principal object created:

public IPrincipal Login(ILoginCredential pCredential, PersistenceManager pManager) {

AppIdentity identity = GetAppIdentity(pCredential, pManager);

String[] roles = GetUserRoles(pManager, identity);

IPrincipal principal = new GenericPrincipal(identity, roles);

}
 
In GetUserRoles() you need to provide the authorized roles for the user as an array of strings:
 

/// <summary>

/// Get the user's roles

/// </summary>

/// <param name="pManager">PersistenceManager for retrieving roles from persistent storage.</param>

/// <param name="pIdentity">Identity of the user who has the roles.</param>

private static string[] GetUserRoles(PersistenceManager pManager, AppIdentity pIdentity) {

// Todo: Get the roles via the UserId in the identity.

// pIdentity.AuthenticationType may figure in role determination.

return new string[] { };

}

These will be placed in the Principal object and returned to the client, where the Principal will be set as the user of the application.
 
By placing
 
<Roles>
    <Role Allow="rolename"/>
</Role>
 
tags within Modules in the ProfileCatalog.xml file, you cause CAB to check the user's roles [via IPrincipal.IsInRole()] before loading the module.
 
You are also free to include role based security to restrict functionality within your code.  See:
 
 
Hope this answers your questions.
 
Bill J
Back to Top
orcities View Drop Down
Senior Member
Senior Member
Avatar

Joined: 28-Aug-2007
Location: United States
Posts: 454
Post Options Post Options   Quote orcities Quote  Post ReplyReply Direct Link To This Post Posted: 21-Sep-2007 at 12:19pm
Thanks again.
 
I tried to put the form implementation in there like I did in the last Cabana release but I must have did something wrong.
 
 
Back to Top
orcities View Drop Down
Senior Member
Senior Member
Avatar

Joined: 28-Aug-2007
Location: United States
Posts: 454
Post Options Post Options   Quote orcities Quote  Post ReplyReply Direct Link To This Post Posted: 21-Sep-2007 at 1:42pm
Since we want to seperate module from presentation. Where do you recommend putting the LoginForm. I don't really want to create a ref in the model project of windows.forms unless it is really necessary.
Back to Top
Bill Jensen View Drop Down
IdeaBlade
IdeaBlade
Avatar

Joined: 31-Jul-2007
Location: United States
Posts: 229
Post Options Post Options   Quote Bill Jensen Quote  Post ReplyReply Direct Link To This Post Posted: 21-Sep-2007 at 2:00pm
GetCredential() is in the AppAuthenticationService in your Foundation project that already has a reference to System.Windows.Forms.  It's not part of the model project.
Back to Top
orcities View Drop Down
Senior Member
Senior Member
Avatar

Joined: 28-Aug-2007
Location: United States
Posts: 454
Post Options Post Options   Quote orcities Quote  Post ReplyReply Direct Link To This Post Posted: 21-Sep-2007 at 3:25pm
I have one problem.
 
The roles are getting stuffed but not implemented.
 
When I remove [DebuggerNonUserCode] from Authenticate I am able to trace and see that it stuffs roles. But it isn't implementing my rules.
 
My profile Catalog has the following.

<Section Name="SecurityModule">

<Dependencies>

<Dependency Name="Foundation" />

</Dependencies>

<Modules>

<ModuleInfo AssemblyFile="LOC.CEMS.SecurityModule.dll" />

<Roles>

<Role Allow="Chuck"/>

</Roles>

</Modules>

</Section>

Chuck doesn't exist as a role so I should never see the module correct?

Back to Top
Linguinut View Drop Down
Senior Member
Senior Member
Avatar

Joined: 14-Jun-2007
Location: United States
Posts: 394
Post Options Post Options   Quote Linguinut Quote  Post ReplyReply Direct Link To This Post Posted: 21-Sep-2007 at 3:34pm
It may be a 'typo', but the Roles tag needs to be inside ModuleInfo

<
ModuleInfo AssemblyFile="Company.App.Module.dll">
    <
Roles>
        <
Role Allow="Chuck"/>
    </
Roles>
</
ModuleInfo>
Back to Top
orcities View Drop Down
Senior Member
Senior Member
Avatar

Joined: 28-Aug-2007
Location: United States
Posts: 454
Post Options Post Options   Quote orcities Quote  Post ReplyReply Direct Link To This Post Posted: 21-Sep-2007 at 4:22pm
Tx. I will give it a try on Monday.
Back to Top
 Post Reply Post Reply

Forum Jump Forum Permissions View Drop Down