【问题标题】:Is it possible to have Oauth in WCF Webservice?是否可以在 WCF Webservice 中使用 Oauth?
【发布时间】:2020-11-16 20:02:57
【问题描述】:

我目前有为 URL 创建代理接口的 Web 服务调用。我需要更新应用程序以接受 Oauth 2.0。是否可以将 Oauth 2.0 与 WCF Webservice 调用一起使用?

这是我的代理接口初始化。我像普通的类初始化一样使用它。

 var client = ServiceClient.CreateProxyInterface<MyWebServiceClass>(WebServiceUrl);

在代理接口中,我进行一些授权检查并创建所请求对象的实例并将其返回给客户端

public static TInterface CreateProxyInterface<TInterface>(string ServiceUrl) where TInterface : class
    {
       var UseClientCertificate = true;
      
      if (ServiceClient.IsUnsecuredHttpService(ServiceUrl, UseClientCertificate))
        ServiceUrl = new UriBuilder(ServiceUrl)
        {
          Scheme = Uri.UriSchemeHttps,
          Port = -1
        }.Uri.ToString();
     
     var key =  TInterface.ToString() + ServiceUrl + UseClientCertificate.ToString();
     ChannelFactory myChannelFactory = ServiceClient.FactoryCache[key];
     proxy = ((ChannelFactory<TInterface>) mlifChannelFactory1.Factory).CreateChannel();
     
     return proxyInterface;
    }

然后客户端可以调用该类中的方法

 var address = client.GetAddress(personId);

【问题讨论】:

    标签: wcf oauth-2.0 webservice-client channelfactory


    【解决方案1】:

    在服务端,可以自定义一个类继承ServiceAuthorizationManager,然后重写ServiceAuthorizationManager中的CheckAccessCore方法来实现。 下面是我从之前的答案中找到的一个例子:OAuth and WCF SOAP service。经过我的尝试,他的例子是有效的,所以我认为它应该对你有所帮助。

     public class OAuthAuthorizationManager : ServiceAuthorizationManager
        {
            protected override bool CheckAccessCore(OperationContext operationContext)
            {
                // Extract the action URI from the OperationContext. Match this against the claims 
                // in the AuthorizationContext. 
                string action = operationContext.RequestContext.RequestMessage.Headers.Action;
        
                try
                {
                    //get the message
                    var message = operationContext.RequestContext.RequestMessage;
        
                    //get the http headers
                    var httpHeaders = ((System.ServiceModel.Channels.HttpRequestMessageProperty)message.Properties.Values.ElementAt(message.Properties.Keys.ToList().IndexOf("httpRequest"))).Headers;
        
        
                //get authorization header
                var authHeader = httpHeaders.GetValues("Authorization");
    
                if (authHeader != null)
                {
                    var parts = authHeader[0].Split(' ');
    
                    if (parts[0] == "Bearer")
                    {
                        var tokenClaims = ValidateJwt(parts[1]);
                        foreach (System.Security.Claims.Claim c in tokenClaims.Where(c => c.Type == "http://www.contoso.com/claims/allowedoperation"))
                        {
                            var authorized = true;
                            //other claims authorization logic etc....
                            if(authorized)
                            {
                                return true;
                            }
                        }
                    }
                }
                return false;
    
            }
            catch (Exception)
            {
                throw;
            }
    
        }
    
        private static IEnumerable<System.Security.Claims.Claim> ValidateJwt(string jwt)
        {
            var handler = new JwtSecurityTokenHandler();
            var validationParameters = new TokenValidationParameters()
            {
                ValidAudience = "urn://your.audience",
                IssuerSigningKey = new InMemorySymmetricSecurityKey(Convert.FromBase64String("base64encoded symmetric key")),
                ValidIssuer = "urn://your.issuer",
                CertificateValidator = X509CertificateValidator.None,
                RequireExpirationTime = true
            };
    
            try
            {
                SecurityToken validatedToken;
                var principal = handler.ValidateToken(jwt, validationParameters, out validatedToken);
    
                return  principal.Claims;
    
            }
            catch (Exception e)
            {
                return new List<System.Security.Claims.Claim>();
            }
    
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-09
      • 1970-01-01
      • 1970-01-01
      • 2010-11-11
      • 2011-10-10
      相关资源
      最近更新 更多