Username & Claims Security When Accessing WCF

Sep 2, 2014 at 11:23 PM

In work we have a database in the office which is accessed via WCF Web services. I have to create an externally hosted ASP.NET Web Forms application (.NET 4.5) which accesses these internal Web services. The usernames and passwords are stored in the database behind a login.svc Web service.

Having followed the 'Identity and Access Control in WCF 4.5' PluralSight course, using the UserNameMixed code within the WcfIdentity45 solution, I have managed to use the relevant parts in a test solution. Once I publish to IIS with a self signed certificate I can authenticate with the Web service and bring back some claims

Server Code
    public class ClaimsTransformer : ClaimsAuthenticationManager
        public override ClaimsPrincipal Authenticate(string resourceName, ClaimsPrincipal incomingPrincipal)
            //"\nClaims transformation....\n".ConsoleYellow();

            var strMessage = String.Format("Authenticated:{0} Name:{1}", incomingPrincipal.Identities.First().IsAuthenticated, incomingPrincipal.Identities.First().Name);

            //incomingPrincipal.Identities.First().AddClaim(new Claim("TimeAtService", DateTime.Now.ToLongTimeString()));

            incomingPrincipal.Identities.First().AddClaim(new Claim("IFBUserID", "1"));
            incomingPrincipal.Identities.First().AddClaim(new Claim("RepairingGarageID", "540"));
            incomingPrincipal.Identities.First().AddClaim(new Claim("Further Info", strMessage));

            return incomingPrincipal;
Client Code
protected void btnLogin_Click(object sender, EventArgs e)
                var factory = new ChannelFactory<wsClaimsService.ClaimsServiceContract>("*");

                factory.Credentials.UserName.UserName = txtUsername.Text;
                factory.Credentials.UserName.Password = txtPassword.Text;

                var proxy = factory.CreateChannel();
                var id = proxy.GetIdentity();

                divMessage.InnerHtml = String.Format("Principal: {0}", id.PrincipalType);
                divMessage.InnerHtml += String.Format("<br/>Identity: {0}", id.IdentityType);

                FormsAuthentication.SetAuthCookie(txtUsername.Text, true);
                //FormsAuthentication.RedirectFromLoginPage(txtUsername.Text, true);

                id.Claims.ForEach(c => ShowClaim(c));

                //Recommended way to get at user
                //var user = System.Security.Claims.ClaimsPrincipal.Current;
            catch (Exception ex)
                divMessage.InnerHtml = ex.Message;
My problem is that I have not quite grasped how I can log in using forms authentication, and then use that login to access the Web services and return claims with every call. This code appears to want a username and password with every call to a Web service
                factory.Credentials.UserName.UserName = txtUsername.Text;
                factory.Credentials.UserName.Password = txtPassword.Text;
but surely I am not going to know the password for every Web service call unless I store it somehow on the client/cache? Is there some way for the Web services to know once I have logged in via login.svc so I can get at cases.svc etc. without having to login again?

I know that caching was mentioned in one video I think to cache the users' claims/credentials. I need to add about 5 claims which will always be accessible to the user e.g. UserID, RepairingGarageID, RepairingGarageGroupID. Currently all of this is stored in separate cookies. I want to use 1 cookie to store the fact that I am logged in, and bring back the rest via claims.

All other Web services will require a username and password to get access, so the user will have to be logged in. Access permission/choices will be made via the relevant claims like UserID.

Is the solution to cache the user's credentials using the username as a key? Then have business classes which inherit some security class which authenticates on every call?

Any help would be greatly appreciated as I am getting very confused. Thank you.