WCF Authentication using SQL Membership Provider

2019-01-20 02:26发布

问题:

Hopefully you folks can clarify some of this for me. I have a web-application using the Sql Membership Provider and it talks to a second web-application through a WCF Service. Both applications share the same Sql Membership Provider datastore...but I need each WCF Service call to authenticate the user.

Now, I've looked at a LOT of samples, but I feel like the samples I've seen either leave out certain code because it "should" be obvious to me, or I mis-understand how WCF handles the request (see expected code below).

I'm grateful for any help...

HERE'S WHAT I ALREADY KNOW HOW TO DO

  1. I know how to configure the Sql Membership on both ends.
  2. I know how to setup the wsHttpBinding
  3. I know how to setup the services certificate used in transport security

HERE'S WHAT I AM CONFUSED ON

  1. How can I pass the Membership password (...you can't)
  2. Do I pass the authentication cookie? If so, how?
  3. Do I create a "known" username and password not related to the user (themselves)?

IN THE WEB CLIENT I WOULD EXPECT TO SEE CODE SOMETHING LIKE THIS

protected void btnLogin_Click(object sender, EventArgs e)
{
    // Logging into the web-application is known and easy.
    if (Membership.ValidateUser("MyUserName", "MyPassword"))
    {
        FormsAuthentication.SetAuthCookie("MyUserName", true);
        FormsAuthentication.RedirectFromLoginPage("MyUserName", false);
    }
}

protected ServiceReference1.Contractor getContractor(Int32 key)
{
    // I expect something "like" this on the client call.
    MembershipUser user = Membership.GetUser("MyUserName");

    ServiceReference1.FishDataClient wcfService = new ServiceReference1.FishDataClient();

    // You can't retreive the users password directly,
    // nor can you get the hash from the SqlMembershipProvider.
    wcfService.ChannelFactory.Credentials.UserName.UserName = user.UserName;
    // So doing something like this would not be possible.
    wcfService.ChannelFactory.Credentials.UserName.Password = "??????";

    // So how is the web service going to authenticate the user from it's
    // references to the same SqlMembershipProvider (database).
    ServiceReference1.Contractor contractor = wcfService.GetContractor(key);

    wcfService.Close();
    wcfService = null;

    return contractor;
}

IN THE WCF SERVICE I WOULD EXPECT TO SEE CODE SOMETHING LIKE THIS

[PrincipalPermission(SecurityAction.Demand, Role = "User")]
public Contractor GetContractor(Int32 key)
{
    ServiceSecurityContext context = ServiceSecurityContext.Current;
    Contractor contractor = new Contractor();

    // What goes here?  I would expect something like this...
    if (Membership.ValidateUser("???????", "???????"))
        contractor.Get(key);

    return contractor;
}

回答1:

I'm assuming your WCF membership provider and your web application membership provider are using the same backend user set.

If so you would want to share authentication cookies between the applications. You can find more information on how to do that here.

Next you need to pass the authentication cookie that came with the web application request to the WCF service call. You can see how to do that here.

The idea is the user logs into your web application and by doing so is logged into your WCF service.



回答2:

Have a look at "Web to Remote WCF Using Transport Security (Trusted Subsystem, HTTP)" in the links below, I am sure you might find the answer there. There is also the following code which I presume might help:

app.Context.User = new GenericPrincipal(new
       GenericIdentity(username, "Membership Provider"), roles);

also:

NetworkCredential netCred = new NetworkCredential("username", " p@ssw0rd");
asmxwebservice.Service proxy = new asmxwebservice.Service();
proxy.Credentials = netCred;               
proxy.GetData(21, true);

Otherwise I would sugest go back to basics, so ensure you get the expected authentication and authorization configure to work 100% when using the membership and role providers in a asp client (asp.net applicaiton).

Then use the same configuration for membership and roles on the WCF service. The only outstanding part then is to make sure the bindings work correctly.

I have not tried forms authentications yet but have recently achieved implementing windows authentication from a ASP.NET applicaton calling a WCF services hosted in IIS and I have found that a slight mistake in the config file (bindings) could cause your application to break.

By setting the user context to a generic pricipal you should be able to receive the user details on the WCF service side.

I foud the answer by reading between the lines in a number of articles so make sure you have a look at the following:

  • Securing Services
  • patterns & practices Improving Web Services Security
  • Web to Remote WCF Using Transport Security (Trusted Subsystem, HTTP)
  • WCF and ASMX Client to Remote WCF Using Transport Security (Original Caller, HTTP)
  • Authorization In WCF-Based Services

Hope this helps