Pregunta

I thought I'd be able to find information on this topic, but it appears my google-fu is weak today. 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 sights that use Yahoo, or Google, for their provider. And I do remember at least one sight, but don't remember which sight it was, that used Amazon.com as the provider.

If someone can point me in the right direction on documentation for this, that would be great.

EDIT: I remember now that it was Target.com that allows you to use an Amazon.com login.

¿Fue útil?

Solución

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);
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top