Introduction
...
In both cases, the name of the server itself, is webserver1, and the address of the configuration server is tcp://localhost:21233 – more servers can be added, separated by semicolon.
The setting nowait is optional, but if specified it tells the agent not to wait for a connection to the config server and session controller, but instead fail immediately if no connection is present.
Note that in web.config, both the property "cfgservers" and "configservers" can be used to specify the list of config servers – if cfgservers is present it will be used, otherwise configservers.
In web.config, you can change the default name of the cookies that Ceptor expects the session ID to be located within. By default, it looks at the following cookies: "sclSessionID,ppSessionID,sslsessionid,sessionid" – you can change this in appsettings by adding:
...
Code Block | ||
---|---|---|
| ||
<?xml version="1.0" encoding="UTF-8"?> <configuration> <configSections> <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler" /> </configSections> <system.web> <compilation debug="true" /> <authentication mode="Forms"> <forms loginUrl="~/Account/Login.aspx" timeout="2880" /> </authentication> <membership defaultProvider="PPMembershipProvider"> <providers> <clear /> <add name="PPMembershipProvider" type="PortalProtect.Providers.PortalProtectMembershipProvider" applicationName="/" /> </providers> </membership> <profile enabled="true" defaultProvider="PPProfileProvider"> <providers> <add name="PPProfileProvider" type="PortalProtect.Providers.PortalProtectProfileProvider" /> </providers> <properties> <add name="email1" defaultValue="[null]" /> <add name="firstname" defaultValue="x" /> <add name="lastname" defaultValue="[null]" /> <add name="address1" defaultValue="[null]" /> <add name="city" defaultValue="[null]" /> <add name="zipcode" defaultValue="[null]" /> <add name="country" defaultValue="[null]" /> <add name="phone" defaultValue="[null]" /> <add name="phonemobile" defaultValue="[null]" /> </properties> </profile> <roleManager enabled="true" defaultProvider="PPRoleProvider"> <providers> <clear /> <add name="PPRoleProvider" type="PortalProtect.Providers.PortalProtectRoleProvider" applicationName="/" /> </providers> </roleManager> <customErrors mode="Off" /> </system.web> <appSettings> <add key="servername" value="webserver1" /> <add key="cfgservers" value="nio://localhost:21233" /> <add key="nowait" value="true" /> </appSettings> <system.webServer> <modules> <add name="PPAuth" type="PortalProtect.Providers.PPBasicAuthenticationModule, PortalProtect.Agent, Version=1.0.0.0, Culture=neutral, PublicKeyToken=218ecb9b9450d01f" /> </modules> </system.webServer> <log4net> <appender name="EventLogAppender" type="log4net.Appender.EventLogAppender"> <applicationName value="APP - PortalProtect"/> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%date [%thread] %-5level %logger [%ndc] - %message%newline"/> </layout> </appender> <appender name="PortalProtectAppender" type="PortalProtect.Log.RemoteLogAppender"> <servers value="nio://localhost:21236"/>" </appender> <!-- Setup the root category, add the appenders and set the default level --> <root> <level value="INFO" /> <appender-ref ref="EventLogAppender" /> <appender-ref ref="PortalProtectAppender" /> </root> </log4net> </configuration> |
Configurations for
...
Testing
If needed for offline testing, Ceptor .NET Agent supports use of an alternate dummy version of the agent, which implements the IAgent interface, but does not provide real data.
...
What this does, is to make sure that HttpContext.Current.User contains a Ceptor Principal which contains the user identification.
Note that if this HttpModule is not installed, the HttpContext.Current.User will not be correct, and some .NET applications that e.g. require role checking or authorization checks to be performed will not work.
When this module is installed, you can no longer access your website directly, but must access it via the Ceptor Dispatcher.
Note that you can always use PortalProtect.Web.HttpPP.CurrentSession() to retrieve the current session no matter if this HttpModule is installed or not – if the module is not installed, it will instead look for the Ceptor session ID in the cookie ppSessionID or sclSessionID which is one of the two default cookie names Ceptor Dispatcher uses to send the session ID to the IIS.
...
Note that only some of the functionality within a membership provider is supported. Operations that manipulate users, such as creating, or deleting them is not supported. Also querying users via the membership provider is currently not supported.
ValidateUser() with userid/password authentication is supported, and ChangePassword() is supported depending on the authentication plugin which the current user is authenticated with, since it might not support changing of passwords.
Authentication
...
Mode
The preferred authentication in web.config is None, set as follows:
...
This tells the IIS to use custom authentication, usually provided by installing the Ceptor .NET HttpModule.
Use of Forms Login and
...
Logging off
On occasion, Forms Login is used together with Membership Provider – there is no requirement to use it with Ceptor Membership Provider, but if you do you need to add something like this to your web.xml:
...
Note that Ceptor does not support the functionality that modifies roles using the Role Provider, such as creating or deleting new roles or changing role assignment.
Supported methods are: GetAllRoles(), RoleExists(), IsUserInRole() and GetRolesForUser().
For IsUserInRole() and GetRolesForUser() the username must be a session ID or the name of the user in the current session.
...
Ceptor .NET Agent API differs slightly from the java version in syntax, but it essentially offers the same functionality.
As an example, where the java version mainly exposes a number of static methods that all takes a session ID as parameter, e.g. Agent.GetInstance().isLoggedOn(sessionid), the .NET version is more natural to the .NET world, and looks like this:
Agent.GetInstance()[sessionid].IsLoggedOn
Agent.GetInstance()[sessionid] returns an implementation of the ISession interface which exposes methods and attributes that work on this particular session.
Getting the Agent
...
Instance
To obtain an instance of an agent, simply call PortalProtect.Agent.getInstance() – this will return a configured instance of the agent which takes its configuration from web.config if running inside the IIS, and from app.config if running outside the IIS.
You can also manually create a new instance and set it as the default, by calling PortalProtect.Agent.NewInstance(servername, configservers) with the local server/service name and the list of configuration servers. To set it as default, then call PortalProtect.Agent.SetInstance(agent) with the newly created agent.
Getting a
...
Session
To get a session, call Agent.GetInstance()[sessionid] with the appropriate session ID – this will return an instance of PortalProtect.ISession which can be used to reference data within a session, or manipulate the contents of it.
If the session ID was not found – e.g. if the session timed out, it will throw a PortalProtect.SessionNotFoundException.
Getting the
...
Current Session Within an IIS
When running an application inside Internet Information Server, you can obtain a reference to the current session for the user by calling PortalProtect.Web.HttpPP.CurrentSession() – it will return the PortalProtect.ISession object for the current user. It does so by looking at the request cookies and obtaining the session ID from there. The requirement for it to work, is that the request first went through the Ceptor Dispatcher to the IIS server, and that the session cookie forward name in the dispatcher is set to either sclSessionID or ppSessionID. If that is not the case, it will look at the current user for the executing thread, and check if there is a session id present there. If so, it returns that session.
Manipulating
...
State Variables
Once you have a PortalProtect.ISession object, you can use the attribute ISession.StateVariables – it contains a PortalProtect.IState object which contains all current state variables. You can query, delete or add new state variables – refer to the API reference documentation for details.
Reference
Refer to PortalProtect_DotNet_Agent_Documentation.chm in the documentation directory of the Ceptor distribution for complete reference information. Start by looking at PortalProtect.Agent and PortalProtect.ISession, they will provide you with most of the information you need.
...
The relevant error code is available in the "ErrorCode" property on the PortalProtectException, and if the authentication plugin provides an "ErrorMessage" meant for displaying to the user, this is available too in the "ErrorMessage" property.
NemID Integration
Ceptor .NET Agent provides easy access to NemID. You can get a signed applet tag with the relevant parameter by using the class PortalProtect.NemID.NemIDAppletElementGenerator.
The following is part of an example (error handling simplified) of using NemID to login (see full example in the samples/integration/dotnet directory in the Ceptor Distribution).
This snippet originates from NemIDLogin.aspx which provides the user with the NemID login applet, and processes the XMLDSIG document sent from the applet.
...
In this example, we start by checking if we are handling a POST from the applet with the signed output from the applet (or possible an error code) – and calls PortalProtect to login using the data exactly as received from the applet.
If it is not a POST, we are creating the applet tag using NemIDApletElementGenerator to do all the dirty work. It in turn calls Ceptor Server which knows all about the keys and certificates required to do the signing. See Ceptor Users Guide for details on the configuration of the server.
We basically just provide a NemID Provider ID which identifies the certificate to use, and private key to use for signing, and then wi set the URL to point to the preproduction or production NemID environment.
When that is done, we add the javascript required by the NemID Applet, and the generated applet tag and we are done.
Note that this example also generates a challenge value that is added as parameter to the applet – this challenge is then verified (done using PortalProtect.NemID.NemIDHelper) when we receive the data from the applet to ensure that the applet is responding to this particular request. If we do not do this, we risk someone recording an earlier sent login xmldsig from the applet and just replaying it to us.
When signing documents, instead of calling applet.generateLogonAppletElement() to generate the applet tag, just call applet.setSigntext() with the text to sign, and applet.generateSignAppletElement() to generate the applet tag instead. When receiving the data from the applet, call session.Confirm() instead of session.Login() – see the NemIDSign.aspx file in the sample for details.
The parameters to the applet are as described in DanIDs documentation.
...
Code Block |
---|
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net.Http; using System.Threading.Tasks; using Microsoft.Owin.Hosting; using Owin; using Ceptor.Owin; using PortalProtect; using System.Security.Claims; namespace Ceptor.Owin.Test { public class Class1 { static void Main(string[] args) { Console.WriteLine("Attempting to start small local webserver on port 12345"); // Not needed, but creates a session just to verify that the connection to Ceptor server works ISession session = Agent.GetInstance().CreateSession("127.0.0.1"); Console.WriteLine("Created new session: " + session.SessionID); using (WebApp.Start<Startup>("http://localhost:12345")) { Console.ReadLine(); } } } public class Startup { public void Configuration(IAppBuilder app) { app.UseCeptorAuthentication(new CeptorAuthenticationOptions { MapClaimName = ((name, value) => name) }); app.Map("/test", config => { config.Run(context => { context.Response.ContentType = "text/html"; if (context.Request.User != null) { ClaimsPrincipal cp = context.Request.User as ClaimsPrincipal; Console.WriteLine("isAuthenticated: " + cp.Identity.IsAuthenticated); Console.WriteLine("Claims: " + cp.Claims); foreach (var claim in cp.Claims) { Console.WriteLine(claim.Type + "=" + claim.Value); } } return context.Response.WriteAsync("<html><body>test</body></html>"); }); }); app.UseWelcomePage("/"); } } } |
Using Authorization
Configuring Authorization
...
Checks
Configuration-based authorization checks rely on standard .NET mechanisms which uses current principal, so for them to work, the Ceptor .NET Agent HttpModule must be enabled for the application.
You can use e.g. <authorization> tags in the web.config file (see Microsofts documentation for details), or you can authorize individual methods like described here: http://msdn.microsoft.com/en-us/library/system.web.mvc.authorizeattribute.aspx
Example
...
Programmatic Authorization
Once you obtained a PortalProtect.ISession object, you can call CheckPermission() to check if the user as the given ACL permission, or you can call IsMemberOfGroup() to check group membership. If you want to find out if access to an URL is allowed, call IsUrlAllowed() to check if the user in the session has access to that particular URL. See the reference documentation for details. You can also call IsInRole() on the current windows user principal, assuming the Ceptor .NET Agent HttpModule is installed as described earlier in this document.
...