Custom Authentication

Posted by Community Admin on 04-Aug-2018 19:41

Custom Authentication

All Replies

Posted by Community Admin on 04-Dec-2014 00:00

I'm having an issue trying to implement a custom MembershipDataProvider.

I followed this tutorial and everything seems to work OK. My code runs without error, but after a succesful login I get the following error:

Exception information:
    Exception type: ArgumentNullException
    Exception message: Value cannot be null.
Parameter name: value
   at Microsoft.IdentityModel.Claims.Claim..ctor(String claimType, String value, String valueType, String issuer, String originalIssuer)
   at Microsoft.IdentityModel.Claims.Claim..ctor(String claimType, String value, String valueType, String issuer)
   at Microsoft.IdentityModel.Claims.Claim..ctor(String claimType, String value)
   at Telerik.Sitefinity.Security.SitefinityIdentity..ctor(User user, Boolean newLoginDate)
   at Telerik.Sitefinity.Security.Claims.SecurityTokenServiceHttpHandler.SendSimpleWebToken(HttpContextBase context, User user, RequestMessage reqMessage)
   at Telerik.Sitefinity.Security.Claims.SecurityTokenServiceHttpHandler.SendToken(HttpContextBase context, User user, RequestMessage reqMessage, String format)
   at Telerik.Sitefinity.Security.Claims.SecurityTokenServiceHttpHandler.ProcessRequest(HttpContextBase context)
   at Telerik.Sitefinity.Security.Claims.SecurityTokenServiceHttpHandler.ProcessRequest(HttpContext context)
   at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
   at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean & completedSynchronously)

When I use the default provider everything work ok.

I'm manually creating the user object and I don't know if thats the proper way of doing it.

Any idea?

Posted by Community Admin on 09-Dec-2014 00:00

Hello Lucas,

I have test the code from the tutorial using the full code sample of the custom provider and it seems works fine.

Would you please elaborate a little more about "manually creating the user" - how the user is created, through the backend UI or through code?

Regards,
Svetoslav Manchev
Telerik

 
Do you want to have your say in the Sitefinity development roadmap? Do you want to know when a feature you requested is added or when a bug fixed? Explore the Telerik Sitefinity CMS Ideas&Feedback Portal and vote to affect the priority of the items
 

Posted by Community Admin on 09-Dec-2014 00:00

Thanks for your help Svetoslav.

I partially managed to solve the problem yesterday. It was an error on my part.

I'm modifying the sample to work with a web service instead of a database. So I made a mistake Generating the user object.

But my problems are not over... :(

Once I succesfully logged a user in the site, this error appears

"There is no configuration for data provider with the name of "WebApiMembershipProvider" for "Telerik.Sitefinity.Security.UserManager" manager. Please check the spelling of the name and whether such configuration exists. "

And now I can't even go to the login page. Every time I try it this error appears (While loading the login page).

What am I missing?

 

 

Posted by Community Admin on 12-Dec-2014 00:00

Hi Lucas,

Please check once again all the steps in the tutorial and take a special attention of its registration described here.

In case the issue still persists, would you please attache your code here or open a support ticket and to upload it there in order to inspect it in details.

Regards,
Svetoslav Manchev
Telerik

 
Do you want to have your say in the Sitefinity development roadmap? Do you want to know when a feature you requested is added or when a bug fixed? Explore the Telerik Sitefinity CMS Ideas&Feedback Portal and vote to affect the priority of the items
 

Posted by Community Admin on 16-Dec-2014 00:00

Well, I checked all the configuration  and the error persists.

I'm attaching the error page and the code from my provider class. If anyone gets any idea...

And just to be clear:

  1. I go to the login page
  2. I select my provider
  3. write my user and password
  4. the methods "GetUser" and "ValidateUser" are called and executed whitout error.
  5. then the error page appears
  6. If I stop the Project and run it again, this time the login page doesn't appear, just the same error as before

Regards

using System;
using System.Collections.Generic;
using System.Configuration.Provider;
using System.Linq;
using System.Web.Security;
using Telerik.Newtonsoft.Json;
using Telerik.Newtonsoft.Json.Linq;
using Telerik.Sitefinity.Data;
using Telerik.Sitefinity.Model;
using Telerik.Sitefinity.Security;
using Telerik.Sitefinity.Security.Data;
using Telerik.Sitefinity.Security.Model;
using WebAgent.FrontEndSite.Helpers;
 
namespace WebAgent.FrontEndSite.Providers
    public class WebApiMembershipProvider : MembershipDataProvider
    
        private readonly ManagerInfo _managerInfo;
 
        public WebApiMembershipProvider()
            : base()
        
            ProviderName = "WebApiMembershipProvider";
            _managerInfo = new ManagerInfo
            
                ProviderName = ProviderName,
                ManagerType = "Telerik.Sitefinity.Security.UserManager",
                ApplicationName = "/WebApiMembershipProvider"
            ;
        
 
        #region Properties
        public string ProviderName get; set;
        public override string ApplicationName get return ManagerInfo.ApplicationName;
        private ManagerInfo ManagerInfo get return _managerInfo;
 
        public override ProviderAbilities Abilities
        
            get
            
                var abilities = new ProviderAbilities ProviderName = Name, ProviderType = GetType().FullName ;
                abilities.AddAbility("GetUser", true, true);
                abilities.AddAbility("CreateUser", true, true);
                abilities.AddAbility("DeleteUser", true, true);
                abilities.AddAbility("UpdateUser", true, true);
                abilities.AddAbility("ValidateUser", true, true);
                abilities.AddAbility("ResetPassword", true, true);
                abilities.AddAbility("GetPassword", false, false);
                return abilities;
            
        
        #endregion
 
        #region Methods
        protected override object CreateNewTransaction(string transactionName)
        
            return new object();
        
 
        public override void CommitTransaction()
 
        protected override void Dispose(bool disposing)
        
            if (!disposing)
                base.Dispose(false);
        
 
        public override bool EmailExists(string email)
        
            var parameters = new Dictionary<string, string> "mail", email ;
            var result = ServiceClient.Get("api/Security/MailExists", parameters);
            return result == "true";
        
 
        public override bool UserExists(string userName)
        
            var parameters = new Dictionary<string, string> "username", userName ;
            var result = ServiceClient.Get("api/Security/UsernameExists", parameters);
            return result == "true";
        
 
        private User GetSitefinityUser(JObject jsonUser)
        
            var user = new User
            
                ApplicationName = ApplicationName,
                IsBackendUser = jsonUser["field_IsBackendUser"].Value<bool>(),
                Id = new Guid(jsonUser["field_Id"].Value<string>()),
                Email = jsonUser["field_Mail"].Value<string>(),
                Comment = jsonUser["field_Comment"].Value<string>(),
                LastActivityDate = DateTime.UtcNow.AddDays(-1),
                LastModified = DateTime.MinValue,
                LastLoginDate = DateTime.MinValue,
                FailedPasswordAnswerAttemptWindowStart = DateTime.MinValue,
                FailedPasswordAttemptWindowStart = DateTime.MinValue,
                Password = jsonUser["field_Password"].Value<string>() + jsonUser["field_Salt"].Value<string>(),
                Salt = jsonUser["field_Salt"].Value<string>(),
                ManagerInfo = ManagerInfo,
                IsApproved = jsonUser["field_IsApproved"].Value<bool>(),
                //PasswordFormat = 2
            ;
            user.SetUserName(jsonUser["field_UserName"].Value<string>());
            user.SetCreationDate(DateTime.Now);
            user.SetIsLockedOut(jsonUser["field_IsLockedOut"].Value<bool>());
            user.SetLastLockoutDate(DateTime.Now);
            user.SetLastPasswordChangedDate(DateTime.Now);
            user.SetPasswordQuestion(jsonUser["field_Question"].Value<string>());
            return user;
        
 
        public override IQueryable<User> GetUsers()
        
            throw new NotSupportedException();
        
 
        public override User GetUser(Guid id)
        
            var parameters = new Dictionary<string, string> "id", id.ToString() ;
            var result = ServiceClient.Get("api/Security/GetUserById", parameters);
            var user = JsonConvert.DeserializeObject<JObject>(result);
            return GetSitefinityUser(user);
        
 
        public override User GetUserByEmail(string email)
        
            var parameters = new Dictionary<string, string> "mail", email ;
            var result = ServiceClient.Get("api/Security/GetUserByMail", parameters);
            var user = JsonConvert.DeserializeObject<JObject>(result);
            return GetSitefinityUser(user);
        
 
        public override User GetUser(string userName)
        
            var parameters = new Dictionary<string, string> "username", userName ;
            var result = ServiceClient.Get("api/Security/GetUserByLogin", parameters);
            var user = JsonConvert.DeserializeObject<JObject>(result);
            return GetSitefinityUser(user);
        
 
        public override User CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, out MembershipCreateStatus status)
        
            // First we validate the given parameters
            if (!ValidateParameters(ref username, ref password, ref email, ref passwordQuestion, ref passwordAnswer, ref providerUserKey, out status))
                return null;
 
            // Generate a new Salt
            var str = GenerateSalt();
            // Get a UTC DateTime
            var utcNow = DateTime.UtcNow;
            // Create a new user with the parameters entered from the Sitefinity backend
            var newUser = CreateUser((Guid)providerUserKey, username);
            newUser.Password = EncodePassword(password, str, PasswordFormat);
            newUser.PasswordAnswer = EncodePassword(passwordAnswer.ToUpperInvariant(), null, PasswordFormat);
            newUser.Salt = str;
            newUser.Email = email;
            newUser.Comment = string.Empty;
            newUser.IsApproved = isApproved;
            newUser.FailedPasswordAttemptCount = 0;
            newUser.FailedPasswordAttemptWindowStart = utcNow;
            newUser.FailedPasswordAnswerAttemptCount = 0;
            newUser.FailedPasswordAnswerAttemptWindowStart = utcNow;
            newUser.PasswordFormat = (int)PasswordFormat;
            newUser.PasswordAnswer = passwordAnswer;
            newUser.SetPasswordQuestion(passwordQuestion);
            newUser.SetCreationDate(DateTime.Now);
 
            // Add the new user to the Switch in our custom database
            var user = new JObject
                "username",username,
                "firstname","",
                "lastname","",
                "password",password,
                "email",email
            ;
            ServiceClient.Post("api/NewUser", user);
 
            // Return our new Sitefinity User
            return newUser;
        
 
        public override User CreateUser(string userName)
        
            return CreateUser(GetNewGuid(), userName);
        
 
        public override User CreateUser(Guid id, string userName)
        
            if (id == Guid.Empty) throw new ArgumentNullException("id");
            if (!string.IsNullOrEmpty(userName))
            
                LoginUtils.CheckParameter(userName, true, true, true, 256, "userName");
                if (UserExists(userName))
                    throw new ProviderException("Username already exists.");
            
 
            var user = new User ApplicationName = ApplicationName, Id = id ;
            user.SetUserName(userName);
            ((IDataItem)user).Provider = this;
            user.ManagerInfo = ManagerInfo;
            return user;
        
 
        public override bool ValidateUser(string userName, string password)
        
            return ValidateUser(GetUser(userName), password);
        
 
        public override bool ValidateUser(User user, string password)
        
 
            if (user == null) return false;
            var flag = CheckValidPassword(user, password);
            if (flag)
            
                user.LastLoginDate = DateTime.UtcNow;
                user.FailedPasswordAttemptWindowStart = DateTime.UtcNow;
                user.FailedPasswordAttemptCount = 0;
            
            else
                UpdateFailureCount(user, "password");
            return flag;
        
 
        private bool CheckValidPassword(User user, string password)
        
            var parameters = new Dictionary<string, string>
            
                "grant_type","password",
                "username",user.UserName,
                "password",password
            ;
            try
            
                var token = ServiceClient.Post("Token", parameters).Length > 0;
                return true;
            
            catch (Exception)
            
                return false;
            
        
         
        public override void Delete(User item)
        
            throw new NotSupportedException();
        
 
        public override string GetPassword(User user, string answer)
        
            throw new NotSupportedException();
        
 
        public override string GetPassword(string userName, string answer)
        
            throw new NotSupportedException();
        
 
        public override string GetPassword(Guid userId, string answer)
        
            return GetPassword(GetUser(userId), answer);
        
 
        public override string ResetPassword(User user, string answer)
        
            throw new NotSupportedException();
        
 
        public override string ResetPassword(string userName, string answer)
        
            throw new NotSupportedException();
        
 
        public override string ResetPassword(Guid userId, string answer)
        
            throw new NotSupportedException();
        
 
        #endregion
 
        #region Not Supported
 
        public override bool ChangePassword(Guid userId, string oldPassword, string newPassword)
        
            throw new NotSupportedException();
        
 
        public override bool ChangePassword(string userName, string oldPassword, string newPassword)
        
            throw new NotSupportedException();
        
 
        public override bool ChangePassword(User user, string oldPassword, string newPassword)
        
            throw new NotSupportedException();
        
 
        public override bool ChangePasswordQuestionAndAnswer(User user, string password, string newPasswordQuestion, string newPasswordAnswer)
        
            throw new NotSupportedException();
        
 
        public override bool ChangePasswordQuestionAndAnswer(Guid id, string password, string newPasswordQuestion, string newPasswordAnswer)
        
            throw new NotSupportedException();
        
 
        public override bool ChangePasswordQuestionAndAnswer(string userName, string password, string newPasswordQuestion, string newPasswordAnswer)
        
            throw new NotSupportedException();
        
 
        public override System.Collections.IEnumerable GetItems(Type itemType, string filterExpression, string orderExpression, int skip, int take, ref int? totalCount)
        
            throw new NotSupportedException();
        
 
        public override bool UnlockUser(Guid userId)
        
            throw new NotSupportedException();
        
 
        public override bool UnlockUser(string userName)
        
            throw new NotSupportedException();
        
 
        public override bool UnlockUser(User user)
        
            throw new NotSupportedException();
        
        #endregion
 
    

 

Posted by Community Admin on 19-Dec-2014 00:00

Hello Lucas,

Would you please check in the SecurityConfig.config (~/App_Data/Sitefinity/Configuration/) is there registration of your custom membership provider with the same name as in the error: WebApiMembershipProvider, in the list of the " <membershipProviders>" providers.

This settings are in the backend: Administration > Settings > Advanced > Security > Membership Providers > (your provider)

In the example I have tested the settings are: http://screencast.com/t/cMLamuAB.

Regards,
Svetoslav Manchev
Telerik

 
Do you want to have your say in the Sitefinity development roadmap? Do you want to know when a feature you requested is added or when a bug fixed? Explore the Telerik Sitefinity CMS Ideas&Feedback Portal and vote to affect the priority of the items
 

Posted by Community Admin on 19-Dec-2014 00:00

I'm attaching a screenshot of the configuration page in the backend and the fragment of the config:

<membershipProviders>
    <add title="WebApi" description="Web API service" type="WebAgent.FrontEndSite.Providers.WebApiMembershipProvider, WebAgent.FrontEndSite" ApplicationName="/WebApiMembershipProvider" maxInvalidPasswordAttempts="5" enablePasswordReset="True" minRequiredNonalphanumericCharacters="0" minRequiredPasswordLength="7" newPasswordLength="8" passwordAttemptWindow="10" passwordFormat="Clear" requiresQuestionAndAnswer="False" requiresUniqueEmail="True" enablePasswordRetrieval="False" enabled="True" name="WebApi" />
</membershipProviders>

Posted by Community Admin on 24-Dec-2014 00:00

Hi Lucas,

Please try to change the name of the provide as in the provide type (WebApiMembershipProvider) and restart the application.

Regards,
Svetoslav Manchev
Telerik

 
Do you want to have your say in the Sitefinity development roadmap? Do you want to know when a feature you requested is added or when a bug fixed? Explore the Telerik Sitefinity CMS Ideas&Feedback Portal and vote to affect the priority of the items
 

Posted by Community Admin on 29-Dec-2014 00:00

Yup. That Works.
In the provider tag, the "name" attribute must be the same as the class name. I changed that and solved the problem.
Thanks!

This thread is closed