Showing posts with label Customer Portal. Show all posts
Showing posts with label Customer Portal. Show all posts

Tuesday, October 2, 2012

How to change the customer / partner portal V2 to authenticate against the MSCRM only.


How to change the customer / partner portal V2 to authenticate against the MSCRM only.

There is a new portal and the changes are Little bit different than it was in the previous version
Customer portal V1 changes can be found here

Walkthrough:

In order to do it you'll need to download the portal and follow the installation steps, avoid all the stuff regarding the LiveID.
After you've imported the solution and the website data we are ready to go.
1)      Open the website in visual studio.
2)      Edit he web.config.
a.                 Remove
                a.1)
 <add name="Live" connectionString="Application Id=0000000000000000; Secret=00000000000000000000000000000000"/>

 a.2)
 <add key="FederationMetadataLocation" value="https://contoso.accesscontrol.windows.net/FederationMetadata/2007-06/FederationMetadata.xml"/>

                        a.3)
 <membership defaultProvider="CrmMembershipProvider">
                                        <providers>
                                                        <add name="CrmMembershipProvider" type="Microsoft.Xrm.Portal.Web.Security.LiveIdMembershipProvider, Microsoft.Xrm.Portal" liveIdConnectionStringName="Live"/>
                                        </providers>
                                        </membership>

                        a.4) 
<httpRuntime maxRequestLength="102400" requestValidationMode="2.0" requestValidationType="Microsoft.Xrm.Portal.IdentityModel.Web.FederationRequestValidator, Microsoft.Xrm.Portal"/>

                        a.5)
 <add name="LiveId" verb="*" path="LiveID.axd" preCondition="integratedMode" type="Microsoft.Xrm.Portal.IdentityModel.Web.Handlers.LiveIdAccountTransferHandler, Microsoft.Xrm.Portal"/>
                                        <add name="Federation" verb="*" path="Federation.axd" preCondition="integratedMode" type="Microsoft.Xrm.Portal.IdentityModel.Web.Handlers.FederationAuthenticationHandler, Microsoft.Xrm.Portal"/>


a.6) 
<microsoft.identityModel>
<service>
                                        <audienceUris>
                                                        <add value="http://contoso.cloudapp.net/"/>
                                        </audienceUris>
                                        <federatedAuthentication>
                                                        <wsFederation passiveRedirectEnabled="false" issuer="https://contoso.accesscontrol.windows.net/v2/wsfederation" realm="http://contoso.cloudapp.net/" requireHttps="false"/>
                                                        <cookieHandler requireSsl="false"/>
                                        </federatedAuthentication>
                                        <issuerNameRegistry type="Microsoft.IdentityModel.Tokens.ConfigurationBasedIssuerNameRegistry, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
                                                        <trustedIssuers>
                                                                        <add thumbprint="0000000000000000000000000000000000000000" name="https://contoso.accesscontrol.windows.net/"/>
                                                        </trustedIssuers>
                                        </issuerNameRegistry>
                        </service>
        </microsoft.identityModel>
        <microsoft.xrm.portal.identityModel>
                        <registration enabled="true" registrationPath="~/confirm-invite" profilePath="~/profile" accountTransferPath="~/login" requiresInvitation="true"
                                        requiresChallengeAnswer="false" requiresConfirmation="false" invitationCodeDuration="01:00:00"/>
        </microsoft.xrm.portal.identityModel>

b.         Replace the Authentication tag to as follow
<authentication mode="Forms">
<forms loginUrl="/login" timeout="525600"     defaultUrl="/"  />
 </authentication>

3)      Edit \Pages\Login.aspx
a.         Remove                
a.1)
<%@ Register TagPrefix="adx" TagName="AzureAcs" Src="~/Controls/AzureAcs.ascx" %>

a.2)
<adx:AzureAcs runat="server" />

a.3)
<crm:Snippet runat="server" SnippetName="Login/ACS/AccountTransfer/Heading" DefaultText="Live ID Account Transfer" />

a.4)
<p>Already registered with a Windows Live ID account? Sign in to transfer the account to an AppFabric ACS account:</p>

b.         Replace
<crm:LiveIdLoginStatus ID="TransferLiveIdLink" runat="server" LoginImageUrl="https://www.passportimages.com/1033/signin.gif"
LogoutImageUrl="https://www.passportimages.com/1033/signout.gif" />
With
  <asp:Login ID="Login1" runat="server" OnAuthenticate="Login1_Authenticate"></asp:Login>

5)   Edit \Pages\Login.aspx.cs
a.                Add to using
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Microsoft.Crm.Sdk;
using Microsoft.Xrm.Client.Services;
using Microsoft.Xrm.Client;
using Xrm;
using System.Web.Security;

b.                Replace Page_Load
protected void Page_Load(object sender, EventArgs e)
        {
            if ((User != null) && User.Identity.IsAuthenticated)
            {
                var redirectUrl = !string.IsNullOrEmpty(Request.QueryString["ReturnUrl"]) ? Request["ReturnUrl"]: !string.IsNullOrEmpty(Request.QueryString["URL"])? Request["URL"]: "/";
                Response.Redirect(redirectUrl);
            }
        }
c.                 Add
        private Contact _loginContact;

        protected Contact LoginContact
        {
            get
            {
                return _loginContact ?? (_loginContact = XrmContext.ContactSet.FirstOrDefault(c => c.Adx_username == Login1.UserName && c.Adx_LogonEnabled != null && c.Adx_LogonEnabled.Value));
            }
        }

        protected void Login1_Authenticate(object sender, System.Web.UI.WebControls.AuthenticateEventArgs e)
        {
            if (LoginContact == null)
            {
                e.Authenticated = false;
            }
            else
            {
                if (LoginContact.Adx_password == Login1.Password)
                {
                if (LoginContact.Adx_changepasswordatnextlogon != null && LoginContact.Adx_changepasswordatnextlogon.Value)
                    {
                        //var page = ServiceContext.GetPageBySiteMarkerName(Website, "ChangePassword");
                        //string redirectURL = ServiceContext.GetUrl(page) + "?UserName=" + Server.UrlEncode(Login1.UserName) + "&Password=" + Server.UrlEncode(Login1.Password);
                        //Response.Redirect(redirectURL);
                    }
                    else
                    {
                        LoginContact.Adx_LastSuccessfulLogon = DateTime.Now.Date;
                        XrmContext.UpdateObject(LoginContact);
                        XrmContext.SaveChanges();
                        e.Authenticated = true;
                        // Response.Redirect("/");
                        FormsAuthentication.RedirectFromLoginPage(Login1.UserName, true);
                    }
                }
                else
                {
                    e.Authenticated = false;
                }
            }
        }

Compile, Debug and Publish to the IIS.

Download changed portal:

Sunday, September 25, 2011

How to change the customer / partner portal to authenticate against the MSCRM only.


How to change the customer / partner portal to authenticate against the MSCRM only.


There is a new version for the portals, to see how to convert Customer Portal V2 go to http://dynamicslollipops.blogspot.co.il/2012/10/how-to-change-customer-partner-portal.html


This blog is based on few other blogs:
Active Directory Authentication:
http://www.shanmcarthur.net/crm/developers-corner/customer-portal-modifications-for-demo-vpc-without-internet-connectivity
SqlMembershipProvider: http://intergr8it.net/?p=216
Both are great and doing the work.
Yet I had to create another approach.

As you probably know the portals comes with authentication against LiveID, Even that it's best practice and all, sometimes the portal isn't expost to the internet and simpler authentication is needed.

Basically the authentication options are:

1)      LiveID – Each user has to have account in Microsoft LiveId website in order to use the portal.

2)      Active Directory – Each user has to be active directory user (almost same as every MSCRM user)

3)      SqlMemberhipProvider – Each user will be created in separate sql table.

4)      Form authentication – It's up to you (In code) who to authenticate and who not. This is the one we'll use to authenticate user based only on the data in the MSCRM.

In this Solution register page is droped and the crm administrator is registers the users stright in the crm. Once the user is configured in the crm his good to go.

Walkthrough:


In order to do it you'll need to download the portal and follow the installation steps, avoid all the stuff regarding the LiveID.

After you've imported the solution and the website data we are ready to go.

1)      Open the website in visual studio.

2)      Edit he web.config.

a.       Remove the
<add name="Live" connectionString="Application Id=0000000000000000; Secret=00000000000000000000000000000000"/>

From the connectionstring tag

b.      Remove the
<membership defaultProvider="CrmMembershipProvider">
<providers><add name="CrmMembershipProvider" type="Microsoft.Xrm.Portal.Web.Security.LiveIdMembershipProvider, Microsoft.Xrm.Portal" liveIdConnectionStringName="Live"/></providers></membership>

c.        Replace the Authentication tag to as follow
<authentication mode="Forms">
<forms loginUrl="/login" timeout="525600"     defaultUrl="/"  />

 </authentication>

3)      Edit \MasterPages\Default.master.

a.       Replace

<crm:LiveIdLoginStatus ID="LiveLoginStatus" runat="server" LoginNavigateUrl='<%$ CrmSiteMap: SiteMarker=Login, Eval=Url %>'/>

With

<asp:LoginStatus ID="LoginStatus1" runat="server" />

4)      Edit \Pages\Login.aspx

a.        Replace               
<crm:LiveIdLoginStatus ID="LiveIdLink" runat="server" LoginImageUrl="http://www.passportimages.com/1033/signin.gif"

LogoutImageUrl="http://www.passportimages.com/1033/signout.gif" />

With

 <asp:Login ID="Login1" runat="server" OnAuthenticate="Login1_Authenticate"></asp:Login>

5)       Edit \Pages\Login.aspx.cs

a.        Add:
  private Contact _loginContact;



        protected Contact LoginContact

        {

            get

            {

                return _loginContact ??

                (_loginContact = XrmContext.ContactSet

                .FirstOrDefault(c => c.Adx_username == Login1.UserName && c.Adx_LogonEnabled != null && c.Adx_LogonEnabled.Value));

            }

        }

b.        Replace onload:
protected void Page_Load(object sender, EventArgs e)

        {

            if ((User != null) && User.Identity.IsAuthenticated)

            {

                var redirectUrl = !string.IsNullOrEmpty(Request.QueryString["ReturnUrl"])

               ? Request["ReturnUrl"]

               : !string.IsNullOrEmpty(Request.QueryString["URL"])

                   ? Request["URL"]

                   : "/";



                Response.Redirect(redirectUrl);

            }

        }

c.        Add:
  protected void Login1_Authenticate(object sender, System.Web.UI.WebControls.AuthenticateEventArgs e)

        {

            if (LoginContact == null)

            {

                e.Authenticated = false;

            }

            else

            {

                if (LoginContact.Adx_password == Login1.Password)

                {

                    if (LoginContact.Adx_changepasswordatnextlogon.Value)

                    {

                        var page = ServiceContext.GetPageBySiteMarkerName(Website, "ChangePassword");

                        string redirectURL = ServiceContext.GetUrl(page) + "?UserName=" + Server.UrlEncode(Login1.UserName) + "&Password=" + Server.UrlEncode(Login1.Password);

                        Response.Redirect(redirectURL);

                    }

                    else

                    {

                        LoginContact.Adx_LastSuccessfulLogon = DateTime.Now.Date;



                        XrmContext.UpdateObject(LoginContact);

                        XrmContext.SaveChanges();



                        e.Authenticated = true;

                       // Response.Redirect("/");

                        FormsAuthentication.RedirectFromLoginPage(Login1.UserName, true);

                    }

                }

                else

                {

                    e.Authenticated = false;

                }

            }

        }



Compile, Debug and Publish to the IIS.