Powered by MSDN

US - English
NEW! Silverlight 5 is available Learn More

UserService/Authentication issues RSS

12 replies

Last post May 15, 2009 12:24 AM by StefanOlson

(0)
  • StefanOlson

    StefanOlson

    Member

    260 Points

    138 Posts

    UserService/Authentication issues

    May 11, 2009 11:45 PM | LINK

    I'm trying to login using UserService, but unfortunately there is no isPersistent flag on the login function. Is there a reason for this?  Because my login code is in a separate assembly, shared between two Silverlight applications, I want to use UserService rather than using the authentication class that is created as part of the .net ria services generated code (which does have isPersistent on it).

    I'm actually not quite clear why there are two classes for logging in.  In a normal situation, when should we use the authentication class that is built in generated code, and when should we use the user service class?

    In addition, I want users to be able to login with their e-mail address, rather than their username. Unfortunately on the server-side authentication class it is not possible to override the login function and therefore change the username like this:

    string newUserName = Membership.GetUserNameByEmail(userName);
    if (newUserName != null)
    {
    userName = newUserName;
    }

    I tried to create a custom login function, but service functions return InvokeEventArgs rather than LoginCompletedEventArgs.

    ...Stefan

    http://www.olsonsoft.com/blogs/stefanolson
  • StefanOlson

    StefanOlson

    Member

    260 Points

    138 Posts

    Re: UserService/Authentication issues

    May 12, 2009 04:29 AM | LINK

    So, I have done some further investigation.  I've discovered that if I use my own function to log in with an e-mail address then UserService.Current.User is never set and there is no way to set it, so hopefully someone will have some solutions on how to solve the above two problems.

     ...Stefan

    http://www.olsonsoft.com/blogs/stefanolson
  • kylemc

    kylemc

    Contributor

    7231 Points

    1146 Posts

    Microsoft

    Re: UserService/Authentication issues

    May 12, 2009 04:01 PM | LINK

    UserService is intended as a client-side abstraction for authentication and authorization. This should become more evident in later releases. The generated authentication context is just the default way to communicate with the server. In most cases, you should be using the abstraction.

    The second Login signature supports the isPersistent flag.

    UserService.Current.Login(new LoginParameters("username", "password", isPersistent));

    Off the top of my head, I'm not sure whether ASP.NET Membership allows you to use email addresses as usernames. I assume it would, but there might be some character restrictions. If that won't work for you, you could override the ValidateUser method in AuthenticationBase. If you want the email address available on the client, you can add it to your user object and override the GetAuthenticatedUser and GetAnonymousUser methods.

    Kyle

  • StefanOlson

    StefanOlson

    Member

    260 Points

    138 Posts

    Re: UserService/Authentication issues

    May 13, 2009 02:28 AM | LINK

    Kyle,

    Thanks for your suggestion regarding login parameters, that works fine.

    I don't want to use e-mail address as the username, just allow people to log in using their e-mail address, which means I need to translate the e-mail address into the username. As you say, you can use ValidateUser, which I have tried, but the problem is with the login function in AuthenticationBase:

    if (this.ValidateUser(userName, password)) {

     IPrincipal principal = new GenericPrincipal(new Identity("Forms", true, userName), AuthenticationBase<T>.DefaultRoles.ToArray<string>());

     this.IssueAuthenticationToken(principal, isPersistent);

     return this.GetUserCore(principal);

    }

    Because I changed the userName in ValidateUser (using similar code to what I've posted in my original message) but then the creation of the GenericPrincipal doesn't have the new updated userName. So it fails to work properly.

    I do have another problem with the persistent cookie option - when I call UserService.Current.Logout() I get an exception: UserService operation already in progress, but I haven't done anything at all with the user service in that session because I've just restarted.

    ...Stefan

    http://www.olsonsoft.com/blogs/stefanolson
  • kylemc

    kylemc

    Contributor

    7231 Points

    1146 Posts

    Microsoft

    Re: UserService/Authentication issues

    May 13, 2009 04:57 PM | LINK

    I'm hearing two conflicting goals.

    1) Login with email address, not username.

    2) Have email address appear as username in the principal.

    In the snippet above, GetUserCore(principal) calls into GetAuthenticatedUser(). You could override that to populate the user however you like. I'd recommend letting the name property be the username and just adding an email property. It might look something like this.

    protected override UserBase GetAuthenticatedUser(IPrincipal principal)
    {
        // ...
        user.Email = Membership.GetEmailForUser(user.Name);
    }
    
    // ...
    public class User : UserBase
    {
        [ProfileUsage(IsExcluded = true)]
        public string Email { get; set; }
    }
    

    Kyle

  • kylemc

    kylemc

    Contributor

    7231 Points

    1146 Posts

    Microsoft

    Re: UserService/Authentication issues

    May 13, 2009 04:59 PM | LINK

    I'm not sure about the Logout issue. You probably have something running (check the UserService.IsBusy property), but it's difficult to know without more details.

    Kyle

  • StefanOlson

    StefanOlson

    Member

    260 Points

    138 Posts

    Re: UserService/Authentication issues

    May 13, 2009 08:44 PM | LINK

    The logout issue was my fault, there was a bug in my routed command implementation.

    http://www.olsonsoft.com/blogs/stefanolson
  • StefanOlson

    StefanOlson

    Member

    260 Points

    138 Posts

    Re: UserService/Authentication issues

    May 13, 2009 08:52 PM | LINK

    My goal is to be able to login using the e-mail address, or username.  One of the problems with a websites is that it's easy to forget your username, but remembering your e-mail address is much easier, so I want users to log in with their e-mail address.

    The problem I'm having is that the login system requires a username, which is fine, because I can get the username from the e-mail address, but before any login activity occurs I need to replace the e-mail addresses I have been provided as a username with the actual username, so that the new Identity("Forms", true, userName) can be created correctly.

    I don't need to have the e-mail address appear as the username, I need the username to appear as the username.  The problem is that I want to pass in the e-mail address to the login function because that is what the user has given me.

    Hopefully, that makes it clearer :-)

    ...Stefan

    http://www.olsonsoft.com/blogs/stefanolson
  • StefanOlson

    StefanOlson

    Member

    260 Points

    138 Posts

    Re: UserService/Authentication issues

    May 13, 2009 09:49 PM | LINK

     Just try and be completely clear, here is the code that I would like to be able to write, but I currently can't because login is not virtual:

    public override User Login(string userName, string password, bool isPersistent)
    {
        string newUserName = Membership.GetUserNameByEmail(userName);
        if (newUserName != null) // if the user has provided an e-mail address use the username associated with that
        {
            userName = newUserName;
        }
        return base.Login(userName, password, isPersistent);
    }

    ...Stefan

    http://www.olsonsoft.com/blogs/stefanolson
  • kylemc

    kylemc

    Contributor

    7231 Points

    1146 Posts

    Microsoft

    Re: UserService/Authentication issues

    May 14, 2009 07:11 PM | LINK

    After reading your posts a few times, I think you should get the right results if you override ValidateUser, GetAuthenticatedUser, and IssueAuthenticationToken to switch out the username. It's not as easy as just overriding Login, but it should get things working for you.

    Kyle