WCF Custom Validator: How to initialize a “User” object from custom validator

后端 未结 2 1931
余生分开走
余生分开走 2021-01-13 07:44

I have a working custom UserNamePasswordValidator that calls into my Oracle DB.

This class derives from System.IdentityModel.Selectors.UserNamePasswordValidator and

2条回答
  •  暗喜
    暗喜 (楼主)
    2021-01-13 07:55

    I have exactly the same issue.

    I am using an API to connect to my underlying Oracle Database, and I "validate" logon details by opening a connection.

    I then want to store this connection somewhere (easy enough, I will create a connection pool for all the different users), but also create a custom Identity and Principal representing this user, so that once it gets to my custom IAuthorizationPolicy, it doesn't need to reload this information.

    I have done a lot of searching and not found anything so my plan is to do this:

    1. Validate login details in custom UserNamePasswordValidator by opening API connection.

    2. Store opened connection in connection pool under the user name.

    3. When my custom IAuthorizationPolicy.Evaluate() is called, I will look at the generic identity provided:

      IIdentity GetClientIdentity(EvaluationContext evaluationContext)
      {
          object obj;
          if (!evaluationContext.Properties.TryGetValue("Identities", out obj))
              throw new Exception("No Identity found");
      
             IList identities = obj as IList;
             if (identities == null || identities.Count <= 0)
                throw new Exception("No Identity found");
      
             return identities[0];
         }
      

    (sorry I can't get rid of this poor HTML escaping)

    1. I then grab a connection from the pool based on the IIdentity.Name, use this connection to load up user-specific data from the database and store this in a custom Identity and Principal which I set in the EvaluationContext:

      public bool Evaluate(EvaluationContext evaluationContext, ref object state)
      {
          IIdentity identity = GetClientIdentity(evaluationContext);
          if (identity == null)
              throw new Exception();
      
              // These are my custom Identity and Principal classes
              Identity customIdentity = new Identity();
              Principal customPrincipal = new Principal(customIdentity);
              // populate identity and principal as required
              evaluationContext.Properties["Principal"] = customPrincipal;
              return true;
          }
      

    Then I should have access to my custom identity and principal whenever I need it by using System.Threading.Thread.CurrentPrincipal or CurrentIdentity.

    Hope this helps in some way; I'm not sure it's the best way to go about it, but it's the best I've come up with so far...

    Steve

提交回复
热议问题