silverlight-4.0openid-provider

Is it possible to use Amazon.com as an authentication provider


I'm building a Silverlight app that is consuming the Amazon.com product advertising API. I want to add authentication to my app, but instead of using the default forms base authentication, I would like to implement OpenId.

I see many websites that use Yahoo, or Google, for their provider. And I do remember at least one site, target.com, that allows you to use an Amazon.com login.

Can someone point me to the correct documentation to implement this authentication?


Solution

  • I don't know much about OpenID but you pretty much have to write a custom authenticatin service, which isn't that bad. (by the way it will still leverage forms authentication which is actually convienent)

    If you know how to validate via code .....

    On the server side you need three pieces. a class to hold your user data, a class that inherits from forms auth.. and a class that handles the logon exceptions..

    here is an example of the server code (sorry minus the open id check)

    using System.ServiceModel.DomainServices.Server.ApplicationServices;
    
    public class UserDTO : UserBase
    {
        public string Email { get; set; }
    
        //Must be string since will be included in HTTP Headers
        public string Id { get; set; }
    
        public bool CanCreateSomething { get; set;}
    }
    

    using System; using System.Data.Objects; using System.ServiceModel.DomainServices.Hosting;

    [EnableClientAccess]
    public class CustomAuthenticationService : FormsAuthenticationService<UserDTO>
    {
    
    
        protected override UserDTO ValidateCredentials(string name, string password, string customData,
                                                       out string userData)
        {
            UserDTO user = null;
            userData = null;
    
            OpenIDUser OIDusr;
    
            if OIDusr != null)
            {
                user = new UserDTO { Name = OIDusr.Description, Email = OIDusr.PrimaryEmail, Id= OIDusr.Id.ToString() };
            }
    
            if (user != null)
            {
                //Set custom data fields for HTTP session  
                userData = user.PartyId + ":" + user.Email;
            }
    
    
            return user;
        }
    

    }

    [Serializable]
    public class FormsAuthenticationLogonException : Exception
    {
        public FormsAuthenticationLogonException(string message) : base(message){}
    }
    
    public abstract class FormsAuthenticationService<TUser> : DomainService, IAuthentication<TUser>
        where TUser : UserBase
    {
        #region IAuthentication<TUser> Members
    
        public TUser GetUser()
        {
            var currentUser = ServiceContext.User;
            if ((currentUser != null) && currentUser.Identity.IsAuthenticated)
            {
                var userIdentity = currentUser.Identity as FormsIdentity;
                if (userIdentity != null)
                {
                    var ticket = userIdentity.Ticket;
                    if (ticket != null)
                    {
                        return GetCurrentUser(currentUser.Identity.Name, ticket.UserData);
                    }
                }
            }
            return GetDefaultUser();
        }
    
    
        public TUser Login(string userName, string password, bool isPersistent, string customData)
        {
            string userData;
            TUser user = ValidateCredentials(userName, password, customData, out userData);
            if (user != null)
            {
                FormsAuthenticationTicket ticket = new FormsAuthenticationTicket( /* version */
                    1, userName, DateTime.Now, DateTime.Now.AddMinutes(30),
                    isPersistent, userData, FormsAuthentication.FormsCookiePath);
                string encryptedTicket = FormsAuthentication.Encrypt(ticket);
                HttpCookie authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
                HttpContextBase httpContext = (HttpContextBase) ServiceContext.GetService(typeof (HttpContextBase));
                httpContext.Response.Cookies.Add(authCookie);
            }
            else
            {
                HttpContextBase httpContext = (HttpContextBase) ServiceContext.GetService(typeof (HttpContextBase));
                httpContext.AddError(new FormsAuthenticationLogonException("Username or password is not correct."));
            }
            return user;
        }
    
        public TUser Logout()
        {
            FormsAuthentication.SignOut();
            return GetDefaultUser();
        }
    
        public void UpdateUser(TUser user)
        {
            throw new NotImplementedException();
        }
    
        #endregion
    
        protected abstract TUser GetCurrentUser(string name, string userData);
    
        protected virtual TUser GetDefaultUser()
        {
            return null;
        }
    
        protected abstract TUser ValidateCredentials(string name, string password, string customData,
                                                     out string userData);
    }
    

    On the client side .....

        LoginParameters loginParameters = new LoginParameters(UserName, Password);
    
            WebContextBase.Current.Authentication.Login(loginParameters, 
                delegate(LoginOperation operation)      
                {                     
                    if (operation.HasError)    
                    {
                        App.IsBusy = false;
                        operation.MarkErrorAsHandled();
                        UserName = string.Empty;
                        Password = string.Empty;
                        MessageBox.Show("Username or Password is incorrect!");
                        return;                 
                    }
    
                    //Login Success
                    CustomAuthenticationContext authContext = new CustomAuthenticationContext();
                    authContext.Load(authContext.GetUserQuery(), UserLoaded, false);
                }, null);