Filling PrimaryIdentity in WCF

I use simple HTTP headers to pass the token to the WCF service for authentication (to use the basicHTTPBinding function, the WCF service is required, so I, unfortunately, cannot use the canned ws-security implementation). I would like to populate a PrimaryIdentity object so WCF services can validate it to determine the authenticated user.

The problem is that the property OperationContext.Current.ServiceSecurityContext.PrimaryIdentityis read-only while I am trying to populate it. I tried using the SecurityTokenAuthenticators and IAuthorizationPolicy objects to set the authentication information, but this route requires the use of message-level security (for example, always sending a username and password), which I do not want.

Can anyone shed some light on how I can set the PrimaryIdentity field?

+3
source share
3 answers

PrimaryIdentitynot intended to be filled in by you - this is the WCF work task to determine who is calling and set accordingly PrimaryIdentity.

, Windows, WindowsIdentity; ASP.NET, , PrimaryIdentity.

, , - WCF.

:

+4

, IAuthorizationPolicy. WCF (X509, WS-Security Username/pass ..) Context.Properties [ "Identities" ], Evaluate. . , , IIdentity, WCF ServiceSecurityContext.Current.PrimaryIdentity. , , WCF, PrimaryIdentity.Name .

var myIdentity = new MyIdentity("MyId", otherstuff);
evaluationContext.Properties["Identities"] = new List<IIdentity> {myIdentity};

, / .

var identities = evaluationContext.Properties.ContainsKey("Identities")
                                 ? (List<IIdentity>) evaluationContext.Properties["Identities"]
                                 : new List<IIdentity>();

var genericIdentity = identities.Find(x => x.AuthenticationType == "MyUserNamePasswordValidator");

genericIdentity.Name → WSS.

UserPasswordValidator (http://msdn.microsoft.com/en-us/library/system.identitymodel.selectors.usernamepasswordvalidator.aspx), WS-Security Username , WCF . DataPower, , , . true.

+10

... ( , config):

ServiceAuthorizationBehavior author = Description.Behaviors.Find<ServiceAuthorizationBehavior>();
author.ServiceAuthorizationManager = new FormCookieServiceAuthorizationManager();
author.PrincipalPermissionMode = PrincipalPermissionMode.Custom;
author.ExternalAuthorizationPolicies = new List<IAuthorizationPolicy> { new CustomAuthorizationPolicy() }.AsReadOnly();

  internal class FormCookieServiceAuthorizationManager : ServiceAuthorizationManager
  {
     public override bool CheckAccess(OperationContext operationContext)
     {
        ParseFormsCookie(operationContext.RequestContext.RequestMessage);
        return base.CheckAccess(operationContext);
     }
     private static void ParseFormsCookie(Message message)
     {
        HttpRequestMessageProperty httpRequest = message.Properties[HttpRequestMessageProperty.Name] as HttpRequestMessageProperty;
        if (httpRequest == null) return;

        string cookie = httpRequest.Headers[HttpRequestHeader.Cookie];
        if (string.IsNullOrEmpty(cookie)) return;

        string regexp = Regex.Escape(FormsAuthentication.FormsCookieName) + "=(?<val>[^;]+)";
        var myMatch = Regex.Match(cookie, regexp);
        if (!myMatch.Success) return;

        string cookieVal = myMatch.Groups["val"].ToString();
        FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(cookieVal);
        Thread.CurrentPrincipal = new GenericPrincipal(new GenericIdentity(authTicket.Name), new string[0]);
     }
  }
  internal class CustomAuthorizationPolicy : IAuthorizationPolicy
  {
     static readonly string _id = Guid.NewGuid().ToString();
     public string Id
     {
        get { return _id; }
     }

     public bool Evaluate(EvaluationContext evaluationContext, ref object state)
     {
        evaluationContext.Properties["Principal"] = Thread.CurrentPrincipal;
        evaluationContext.Properties["Identities"] = new List<IIdentity> { Thread.CurrentPrincipal.Identity };
        return true;
     }

     public ClaimSet Issuer
     {
        get { return ClaimSet.System; }
     }
  }

AspNetCompatibility, FormCookieServiceAuthorizationManager :

 internal class FormCookieServiceAuthorizationManager : ServiceAuthorizationManager
 {
    public override bool CheckAccess(OperationContext operationContext)
    {
       Thread.CurrentPrincipal = HttpContext.Current.User;
       return base.CheckAccess(operationContext);
    }
 }
+4

Source: https://habr.com/ru/post/1745355/


All Articles