3

I have a WCF service like this:

[ServiceContract( SessionMode=SessionMode.Required)]
public interface IService
{
    [OperationContract(IsInitiating = true, IsTerminating = false)]
    void login(string id);

    [OperationContract(IsInitiating = false, IsTerminating = false)]
    string getdata();
}



public class Service : IService
{
    public void login(string hashedid)
    {
        if (username != "someusername" || password != "somepassword")
        {
            // can not get data
        }
        else
        {
            // can get data
        }
    }

    public string getdata()
    {
        return "these are data";
    }
}

How can I write the method login and create the client application? Thanks you.

hanuman0503
  • 219
  • 6
  • 19
  • public void login(string username, string password) { if (username != "someusername" || password != "somepassword") { throw new Exception("Unknown username or password"); } else { // can get data } } is this ok? – hanuman0503 May 04 '10 at 07:38
  • 2
    This is correct in terms of the two parameters but when you call getdata() you will still not know if that person has authenticated earlier and the exception you are throwing will not be transported back to the client. You need to throw a FaultException or add ServiceDebugBehavior() with IncludeExceptionDetailInFaults=true to your service host behaviors. – flayn May 04 '10 at 10:37

1 Answers1

7
[ServiceContract( SessionMode=SessionMode.Required)]
public interface IService
{
    [OperationContract(IsInitiating = true, IsTerminating = false)]
    void login(string username, string password);

    [OperationContract(IsInitiating = false, IsTerminating = false)]
    string getdata();
}



public class Service : IService
{
// todo: make threadsafe!
    public static List<Guid> authenticated = new List<Guid>();

    public void login(string username, string password)
    {

        if (username == "correctUsername" || password == "correctPassword")
        {
            // user has given correct username/pasword
            Guid currentSessionId = OperationContext.Current.SessionId;

        // note: can throw Exception when calling login twice or more, check if item exists first
            authenticated.Add(currentSessionId);
        }


    }

    public string getdata()
    {
        Guid currentSessionId = OperationContext.Current.SessionId;
        if (List.Contains(currentSessionId)
        {
                return "these are data";
        }

        return String.Empty;
    }
}

You can identify a session by the current Session id. After a user authenticates correctly you can add this session to the list of authenticated session.

Mind: This is just some pseudo code. The session id should removed when the session is cloced, the list I use is not threadsafe,... But I hope this helps you get into the right direction.

flayn
  • 5,272
  • 4
  • 48
  • 69
  • 2
    You'll also need to use a binding that supports sessions for this to work. See http://msdn.microsoft.com/en-us/library/ms730879.aspx – Chris O May 04 '10 at 10:50
  • Thanks you everybody. I have more question: if I have more getmoredata or getsomedata method so I also have to check SessesionID first? – hanuman0503 May 05 '10 at 09:14
  • Yes. Whenever you want to make sure that the user is logged in, you have to check if the session ID is in the list. – flayn May 05 '10 at 12:22
  • Thank you for this information, it beats letting the user send some manual authentication id for every request. I know this this is an old thread, but perhaps you can still tell me if there is a security-issue possible here. Thank you in advance. – Silvermind Feb 06 '13 at 10:35
  • 1
    @Silvermind: It really depends on your bindings. If you use this with a http Binding it is unsecure. – flayn Feb 06 '13 at 11:42
  • @FlorianGerhardt Ok, I would have to use an ssl like httpsBinding than? Thank you for your time. – Silvermind Feb 06 '13 at 11:52
  • It really depends where you want to use it. If you are inside a Windows Domain you can use a binding that supports encryption with the Windows User token like net.tcp. For a public service you should probably go with https. – flayn Feb 06 '13 at 14:43