问题描述
我知道webservicehost类上的身份验证并不完全符合身份验证标准(当用户输入错误的凭据时,返回403禁止而不是提示输入另一组凭据)。
I'm aware that the authentication on the webservicehost class does not adhere fully to authentication standards (returns 403 forbidden rather than prompting for another set of credentials when the user enters incorrect credentials).
我仍然希望实现这种基本身份验证(会话开始时的用户名和密码,不需要HTTPS - 见下图),因为它符合我对小型家庭项目的需求。
I'd still like to implement this basic authentication (username and password at the start of the session, HTTPS unnecessary - see picture below) as it suits my needs for a small home project.
我为myService提供的代码如下:
The code I have for myService is as follows:
Imports System.IO
Imports System.Text
Imports System.ServiceModel
Imports System.ServiceModel.Web
Imports System.ServiceModel.Channels
<ServiceContract()>
Public Class myService
<OperationContract(), WebGet(UriTemplate:="/xml/{argument1}/{argument2}")>
Public Function XML(argument1 As String, argument2 As String) As Stream
requestCounter += 1
Console.WriteLine("xml data request at " & DateTime.Now.ToString() & ", request count= " & requestCounter)
Console.WriteLine(WebOperationContext.Current.IncomingRequest.UserAgent.ToString())
Return _ReturnXML("<xmlresponse><data><argument1>" & argument1 & "</argument1><argument2>" & argument2 & "</argument2></data><server><serverlivesince>" & serverStart.ToString() & "</serverlivesince><pageservetime>" & DateTime.Now.ToString() & "</pageservetime><requestcount>" & requestCounter & "</requestcount></server></xmlresponse>")
'returns the first two parameters, and the time and date
End Function
Private Shared Function _ReturnXML(_result As String) As Stream
Dim data = Encoding.UTF8.GetBytes(_result)
WebOperationContext.Current.OutgoingResponse.ContentType = "text/xml; charset=utf-8"
WebOperationContext.Current.OutgoingResponse.ContentLength = data.Length
Return New MemoryStream(data)
End Function
End Class
然后我有类似的代码来返回HTML以及接受其他参数组合。
I then have similar code to return HTML as well as accept other parameter combinations.
在我的Main类中,我已实例化并打开此服务:
In my Main class I've instantiated and opened this service as:
Dim varWebService = New WebServiceHost(GetType(MyWebService), New Uri("http://0.0.0.0/"))
varWebService.Open()
有人能为我提供代码来实现这种简单的身份验证吗?或者给我一个完整的教程?感谢您的帮助
Could anyone provide me with code to implement this simple authentication? Or point me to a thorough tutorial? Thanks for any help
推荐答案
您可以通过继承自定义WebServiceHost并更改一些默认参数来编写自定义WebServiceHost。
You can write a custom WebServiceHost by inheriting from it and change some default parameters like below.
代码中唯一的变化是
Dim varWebService = New AuthenticatedWebServiceHost(GetType(MyWebService), New Uri("http://0.0.0.0/"))
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IdentityModel;
using System.IdentityModel.Selectors;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.ServiceModel.Security;
using System.ServiceModel.Description;
namespace StackOverflow
{
public class AuthenticatedWebServiceHost : WebServiceHost
{
public AuthenticatedWebServiceHost(Type type, Uri url)
{
IDictionary<string, ContractDescription> desc = null;
base.InitializeDescription(type, new UriSchemeKeyedCollection());
base.CreateDescription(out desc);
var val = desc.Values.First();
WebHttpBinding binding = new WebHttpBinding();
binding.Security.Mode = WebHttpSecurityMode.TransportCredentialOnly;
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
base.Credentials.UserNameAuthentication.UserNamePasswordValidationMode = UserNamePasswordValidationMode.Custom;
base.Credentials.UserNameAuthentication.CustomUserNamePasswordValidator = new CustomUserNamePasswordValidator();
base.AddServiceEndpoint(val.ContractType, binding, url);
}
//Possible next question:
//"How can I get the name of the authenticated user?"
public static string UserName
{
get
{
if (OperationContext.Current == null) return null;
if (OperationContext.Current.ServiceSecurityContext == null) return null;
if (OperationContext.Current.ServiceSecurityContext.PrimaryIdentity == null) return null;
return OperationContext.Current.ServiceSecurityContext.PrimaryIdentity.Name;
}
}
public class CustomUserNamePasswordValidator : UserNamePasswordValidator
{
public override void Validate(string userName, string password)
{
//Your logic to validate username/password
if (userName != password)
throw new SecurityAccessDeniedException();
}
}
}
}
这篇关于如何实现WebServiceHost身份验证?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!