来自JSON客户端调用的ServiceStack身份验证C#出错

时间:2015-07-16 15:44:09

标签: c# web-services authentication servicestack ormlite-servicestack

我创建了100多个没有任何Web安全性的Web服务。现在我想在现有服务上实现Web安全性。所以我从非常基本的身份验证(基本/自定义凭证)开始,通过以下链接:

https://github.com/ServiceStack/ServiceStack/wiki/Authentication-and-authorization#oauth2-providers

但是我无法在测试时从JSON客户端验证服务堆栈Web服务。我刚刚通过“CredentialsAuthProvider”创建了非常基本的Web安全性。它总是返回错误

"The remote server returned an error: (401) Unauthorized."

我尝试过Basic和CustomeCredentials身份验证。我不知道我在哪里出现了错误。

如果我直接从浏览器(Firefox或Chrome)URL执行如下

,它运行正常
1st time execute for authentication  :

    http://192.168.1.120/PatientMeasurementDatabase/auth/credentials?Username=john&Password=test

输出:

    Session Id  uWv4e9BpSUwScur7KxD6
    User Name  John
    Response Status

第二次执行:

    http://192.168.1.120/PatientMeasurementDatabase/GetActiveUserId/

输出正常:

    GetActiveUserId
    kpugj_01_07_2015_12_44_23
    isiqz_01_07_2015_12_49_08 
    jjrma_01_07_2015_13_48_56

----------- Servicestack webservice ApplicationHost.cs --------

    public class CustomCredentialsAuthProvider : CredentialsAuthProvider
        {
            public override bool TryAuthenticate(IServiceBase authService,
            string userName, string password)
            {
                return userName == "john" && password == "test";
            }
        }

    public class ApplicationHost : AppHostHttpListenerBase
        {
            /// <summary>
            /// This default constructor passes the name of our service “PersonService” as
            /// well as all assemblies that need to be loaded – in this case we only need to
            /// use the current assembly so I have passed that using typeof()
            /// </summary>
            public ApplicationHost()
            : base("Patient Measurement Database", typeof(ApplicationHost).Assembly)
        {

        }

public override void Configure(Funq.Container container)
        {
            string database_path = Common.getDatabaseConnectionString();

            container.Register<IDbConnectionFactory>(c => new OrmLiteConnectionFactory(database_path, MySqlDialectProvider.Instance));

            using (var db = container.Resolve<IDbConnectionFactory>().Open())
            {
                CreateTables(db);
            }

            Plugins.Add(new CorsFeature()); //Enable CORS

            Plugins.Add(new RazorFormat());

            // register storage for user sessions 
            container.Register<ICacheClient>(new MemoryCacheClient());
            container.Register<ISessionFactory>(c => 
                                                new SessionFactory(
                                                c.Resolve<ICacheClient>()));

            Plugins.Add(new CorsFeature(allowedHeaders: "Content-Type, Authorization"));

            Plugins.Add(new AuthFeature(() => 
                new AuthUserSession(), new AuthProvider[] 
               {  
                  new CustomCredentialsAuthProvider(), 
               }));
       }

-------------------------------服务类-------------- ---

    [Authenticate]
        [Route("/GetActiveUserId ", "GET, POST")]
        public class GetActiveUserId
        {
        }

       public List<GetActiveUserId > Any(GetActiveUserId  request)
            {
            try
            {
                CRUDFunctions objCRUDFunctions = new CRUDFunctions(Db);
                var record = objCRUDFunctions.GetActiveUserId();
                return record;
            }
            catch (Exception ex)
            { 
                return null;
            }
        }

----------------------------对Servicestack服务器的GET / POST请求的客户端代码如下所示。

              try
                {
      string URL = ("http://192.168.1.120/MeasurementDatabase/json/reply/GetActiveUserId"

      WebRequest req = WebRequest.Create(URL);
                    //WebRequest req = WebRequest.Create(address);
                    CredentialCache ch = new CredentialCache();
                    string UserId =  "john";
                    string Password = "test";
                    string credentials = String.Format("{0}:{1}", UserId, Password);
                    byte[] bytes = Encoding.ASCII.GetBytes(credentials);
                    string base64 = Convert.ToBase64String(bytes);
                    string authorization = String.Concat("Credentials ", base64);
                    req.Headers.Add("Authorization", authorization);

                    req.Method = "POST";
                    // Create POST data and convert it to a byte array.
                    byte[] bytearray = Encoding.UTF8.GetBytes(Data);
                    // Set the ContentType property of the WebRequest.
                    req.ContentType = "application/json";
                    // Set the ContentLength property of the WebRequest.
                    req.ContentLength = bytearray.Length;
                   WebResponse resp = req.GetResponse();
                   StreamReader sr = new StreamReader(resp.GetResponseStream());
                   string str = sr.ReadToEnd().Trim();
      resp.Close();
    }

1 个答案:

答案 0 :(得分:1)

您可以使用C#/.NET Service Clients轻松使用经过身份验证的服务。

如果您使用CredentialsAuthProvider,则可以使用以下身份进行身份验证:

var client = new JsonServiceClient(BaseUrl);

var authResponse = client.Post(new Authenticate {
    provider = CredentialsAuthProvider.Name, //= credentials
    UserName = "test@gmail.com",
    Password = "p@55w0rd",
    RememberMe = true,
});

成功验证服务客户端client实例后,将填充经过身份验证的会话cookie,然后允许调用经过身份验证的服务,例如:

var response = client.Get(new GetActiveUserId());

如果您还注册了BasicAuthProvider,它将使您的服务能够接受内置在服务客户端中的服务客户端HTTP Basic Authentication

client.UserName = "test@gmail.com";
client.Password = "p@55w0rd";

您还可以访问受保护的服务,例如:

var response = client.Get(new GetActiveUserId());

虽然幕后最终会发出2个请求,但是第一个请求会发送一个正常请求,该请求将被401 Unauthorized拒绝,如果服务器指示它已启用BasicAuthProvider,它将重新发送带有HTTP Basic Auth凭据的请求。

您可以通过指定客户端应始终在每次请求时发送Basic Auth来保存额外的auth质询请求的延迟:

client.AlwaysSendBasicAuthHeader = true;