The StudioSelector in Adam takes care of two major taks:
- Single sign on for all the studios
- Allow to user to go to a studio
When creating a custom StudioSelector, at least this functionality must be
provided and this article guides you through the steps required to implement it.
Getting started
Open Visual Studio, create a new ASP.NET Web Application project and add the
required Adam references:
- Adam.Core
- Adam.Tools
- Adam.Web
- Adam.Web.Core
To configure Adam properly for this web application, open the web.config file and
add the configuration section definitions for Adam:
| XML |
1
2
3
4
5
6
7
8
9
|
<configSections>
<section name="Adam.Core"
type="Adam.Core.ConfigurationHandler,Adam.Core"/>
<section name="Adam.Tools"
type="Adam.Tools.ConfigurationHandler,Adam.Tools"/>
<section name="Adam.Web.Core"
type="Adam.Web.Core.Configuration.AdamWebConfiguration, Adam.Web.Core"
allowDefinition="Everywhere"/>
</configSections>
|
Specify the registration and application name to use in Adam. Since we are
creating a custom studio selector, name this application "CustomStudioSelector".
Beside this, specify how Adam should perform its logging:
| XML |
1
2
3
4
5
6
7
8
9
10
11
|
<Adam.Core>
<defaultRegistration name="AdamNet"/>
<applicationName name="CustomStudioSelector"/>
</Adam.Core>
<Adam.Tools>
<logListeners>
<add type="Adam.Tools.LogHandler.EventLogListener,Adam.Tools"
severity="Verbose"/>
</logListeners>
</Adam.Tools>
|
And configure the web behavior of Adam as a custom StudioSelector
| XML |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
<Adam.Web.Core>
<websiteInfo
type="CustomStudioSelector"
title="CustomStudioSelector"
description="CustomStudioSelector" />
<authentication
enabled="true"
activeDirectoryAuthenticationProviderType="Adam.Core.Server.ActiveDirectoryAuthenticationProvider, Adam.Core"
cookieName=".ADAMAUTH"
requireSSL="false"
persistentTimeout="30"
loginUrl="~/Login.aspx"
defaultUrl="~/Default.aspx"/>
</Adam.Web.Core>
|
Single sign on
To implement the single sign on feature in this custom studio selector, we need
to modify the web.config file a bit more.
First, we need to ensure that the authentication cookie created by Adam can be
parsed and decrypted by all studios. To enable this, you must configure the machineKey
element in the system.web
section properly If all your studios are running in the same application
pool, you can use the following configuration on all your studios:
| XML |
1
2
3
4
5
|
<machineKey
decryptionKey="AutoGenerate"
validationKey="AutoGenerate"
decryption="AES"
validation="SHA1" />
|
For more complex setups, you
can find more information on the following MSDN page:
machineKey Element and
How To: Configure MachineKey in ASP.NET 2.0
Next, when need to make sure that the log off functionality is available to all
studios. The log off itself is not the issue here (when the user clicks log off
in any studio, the authentication cookie is cleared and no other studio can use
it anymore). The real problem is the ASP.NET session management. If a user clicks log
off in the asset studio, the ASP.NET session can be cleared in that studio, but the
ASPNET session of the config studio is still available.
To deal with this problem, Adam creates an
ASP.NET session id based upon the Adam session. This ensures that all studios
use the same session id and when the user logs on again, his ASP.NET session id
is changed. You can use the same behavior by setting the
sessionIDManagerType in
the se sessionState
configuration element:
| XML |
1
2
3
|
<sessionState
sessionIDManagerType="Adam.Web.Core.MultiSiteSessionIDManager,
Adam.Web.Core"/>
|
Another item to configure is how authentication is done and who is authorized to
use this application. Because the StudioSelector is the studio that performs a log on to Adam, you
can configure this web application to use Adam authentication or Activve
Directory authentication. For more information, see the help that came with your
Adam installation.
The last step for providing the single sign on is the login page itself. Add a
log Web Form to your application and name it Login.aspx and an Adamlogin
control:
| ASP.NET |
1
|
<awc:AdamLogin runat="server" />
|
See the attached sample code project if you wish to customize the look and feel of the login control.
Log out
Of course, after the user performed a log in, he should be able to log off.
Because we configured everything needed for the single sign on above, it makes
life pretty easy to implement the log off feature (this code will work in any
studio):
| C# |
1
|
AdamAuthentication.SignOut();
|
Selecting a studio
The second feature that must be implemented in a custom studio selector is
actually let the user select a studio.
To get the studios configured in Adam, a helper class can be used:
| C# |
1
|
ReadOnlyCollection<StudioInfo> allStudios = StudioHelper.GetStudios(true);
|
This method returns all studios configured in Adam, but does not take into
account if a user has access to this studio. Checking this is easy: every studio
has a role that indicates whether a user has access to it or not. This code
checks whether the currently logged on user has access to the config studio:
| C# |
1
|
AdamHelper.GetApplication().HasRole("RoleAccessStudioConfigStudio");
|
A StudioInfo object contains the Name, Label and Url of the studio; there is no
link to the image of the studio as you see on the default StudioSelector.
However, all Adam studios have an 'icon.png' file in there root directory, which
makes it pretty easy to create a link to the images (based upon the Url of the
StudioInfo object).
An example of all this can be found in the Default.aspx page of the attached
sample code project. The basic idea is to create a list of studios available to
the user, bind this list to a GridView and use standard ASP.NET databinding to
show the available studios.
Code Behind
| C# |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
/// <summary>
/// Occurs when the page is loading and raises the Load event.
/// </summary>
/// <param name="e">The event data.</param>
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
// When the page initially loads, data bind the grid view to the available studios.
if (this.Page.IsPostBack == false)
{
// Get the studios for this user.
ReadOnlyCollection<StudioInfo> oAllStudios = StudioHelper.GetStudios(true);
// Filter out the studios that are not visible to the user.
List<StudioInfo> oFilteredStudios = new List<StudioInfo>();
foreach (StudioInfo oStudio in oAllStudios)
{
if (this.IsStudioVisible(oStudio.Name) == true)
oFilteredStudios.Add(oStudio);
}
// Assign the filtered studios to the grid view.
this.GridView1.DataSource = oFilteredStudios;
this.GridView1.DataBind();
}
}
/// <summary>
/// Helper method to determine wheter a studio is visible to the current user.
/// </summary>
/// <param name="name">The name of the studio to verify.</param>
/// <returns><b>true</b> when the user is allowed to see the studio; otherwise, <b>false</b>.</returns>
private Boolean IsStudioVisible(string name)
{
// Check if name is 'studio selector'. If so, the studio is never visible.
if (name.Equals("StudioSelector", StringComparison.InvariantCultureIgnoreCase))
return false;
// Check if the user has access to the studio.
return AdamHelper.GetApplication().HasRole("RoleAccessStudio" + name, true);
}
|
Markup
| ASP.NET |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
<asp:GridView ID="GridView1"
runat="server"
AutoGenerateColumns="False">
<Columns>
<asp:ImageField
DataImageUrlField="Url"
DataImageUrlFormatString="{0}icon.png"
HeaderText="Icon" />
<asp:HyperLinkField
DataNavigateUrlFields="Url"
DataTextField="Name"
HeaderText="Studio" />
<asp:BoundField
DataField="Label"
HeaderText="Description" />
</Columns>
</asp:GridView>
|
Wrap up
The sample code attached gives you a starting point to create your own custom
studio selector. Now you can add more features to the studio selector, specific
to meet the needs of your customer.
One of the things asked before is a 'forgot password' feature. This feature has
been implemented in the sample code project attached to this article. Feel free
to use it.