您的位置:首页 > 其它

如何:使用 SOAP 头执行自定义身份验证

2020-01-13 21:23 239 查看
如何:使用 SOAP 头执行自定义身份验证 

下面的自定义解决方案是使用 ASP.NET 生成的,以提供使用 SOAP 头的身份验证机制。该解决方案涉及 Web 服务器上的一个自定义 HTTP 模块,该模块用于执行下列步骤:

  1. HTTP Module分析 HTTP 消息,检查是否是 SOAP 消息。

  2. 如果 HTTP Module检测到 SOAP 消息,它将读取 SOAP 头。

  3. 如果 SOAP 消息的 SOAP 头中含有身份验证凭据,则 HTTP Module引发自定义 global.asax 事件。

在所提供的示例中,HTTP Module对用户进行身份验证并设置 Context 属性,Web 服务可以使用该属性确定客户端是否被授予对 Web 服务的访问权限。

注意

在本示例中,文本是以完全可读的文本方式(不进行加密)通过网络发送的。对您的应用程序来说,如果明文形式不够安全,请添加加密算法。

示例

下面的代码示例是一个 HTTP 模块,它为 SOAP 请求分析 HTTP 消息。如果 HTTP 消息是一个 SOAP 消息,则会引发自定义 WebServiceAuthenticationEvent。

C# 复制代码
using System;
using System.Web;
using System.IO;
using System.Xml;
using System.Xml.XPath;
using System.Text;
using System.Web.Services.Protocols;

namespace Microsoft.WebServices.Security {

public sealed class WebServiceAuthenticationModule : IHttpModule
{
private WebServiceAuthenticationEventHandler
_eventHandler = null;

public event WebServiceAuthenticationEventHandler Authenticate
{
add { _eventHandler += value;}
remove {_eventHandler -= value;}
}

public void Dispose()
{
}

public void Init(HttpApplication app)
{
app.AuthenticateRequest += new
EventHandler(this.OnEnter);
}

private void OnAuthenticate(WebServiceAuthenticationEvent e)
{
if (_eventHandler == null)
return;

_eventHandler(this, e);
if (e.User != null)
e.Context.User = e.Principal;
}

public string ModuleName
{
get{ return "WebServiceAuthentication"; }
}

void OnEnter(Object source, EventArgs eventArgs) {
HttpApplication app = (HttpApplication)source;
HttpContext context = app.Context;
Stream HttpStream = context.Request.InputStream;

// Save the current position of stream.
long posStream = HttpStream.Position;

// If the request contains an HTTP_SOAPACTION
// header, look at this message.
if (context.Request.ServerVariables["HTTP_SOAPACTION"]
== null)
return;

// Load the body of the HTTP message
// into an XML document.
XmlDocument dom = new XmlDocument();
string soapUser;
string soapPassword;

try
{
dom.Load(HttpStream);

// Reset the stream position.
HttpStream.Position = posStream;

// Bind to the Authentication header.
soapUser =
dom.GetElementsByTagName("User").Item(0).InnerText;
soapPassword =
dom.GetElementsByTagName("Password").Item(0).InnerText;
}
catch (Exception e)
{
// Reset the position of stream.
HttpStream.Position = posStream;

// Throw a SOAP exception.
XmlQualifiedName name = new
XmlQualifiedName("Load");
SoapException soapException = new SoapException(
"Unable to read SOAP request", name, e);
throw soapException;
}

// Raise the custom global.asax event.
OnAuthenticate(new WebServiceAuthenticationEvent
(context, soapUser, soapPassword));
return;
}
}
}
Visual Basic 复制代码
Public NotInheritable Class WebServiceAuthenticationModule
Implements IHttpModule

Public Delegate Sub WebServiceAuthenticationEventHandler(ByVal sender As [Object], ByVal e As WebServiceAuthenticationEvent)
Private _eventHandler As WebServiceAuthenticationEventHandler = Nothing

Public Custom Event Authenticate As
WebServiceAuthenticationEventHandler
AddHandler(ByVal value As
WebServiceAuthenticationEventHandler)
_eventHandler = value
End AddHandler
RemoveHandler(ByVal value As
WebServiceAuthenticationEventHandler)
_eventHandler = value
End RemoveHandler
RaiseEvent(ByVal sender As Object,
ByVal e As WebServiceAuthenticationEvent)
End RaiseEvent
End Event

Public Sub Dispose() Implements System.Web.IHttpModule.Dispose

End Sub 'Dispose

Public Sub Init(ByVal app As HttpApplication) Implements System.Web.IHttpModule.Init
AddHandler app.AuthenticateRequest, AddressOf Me.OnEnter

End Sub 'Init

Private Sub OnAuthenticate(ByVal e As WebServiceAuthenticationEvent)
If _eventHandler Is Nothing Then
Return
End If
_eventHandler(Me, e)
If Not (e.User Is Nothing) Then
e.Context.User = e.Principal
End If

End Sub 'OnAuthenticate

Public ReadOnly Property ModuleName() As String
Get
Return "WebServiceAuthentication"
End Get
End Property

Sub OnEnter(ByVal [source] As [Object], ByVal eventArgs As EventArgs)
Dim app As HttpApplication = CType([source], HttpApplication)
Dim context As HttpContext = app.Context
Dim HttpStream As Stream = context.Request.InputStream

' Save the current position of stream.
Dim posStream As Long = HttpStream.Position

' If the request contains an HTTP_SOAPACTION
' header, look at this message.
If context.Request.ServerVariables("HTTP_SOAPACTION") Is Nothing Then
Return
End If
' Load the body of the HTTP message
' into an XML document.
Dim dom As New XmlDocument()
Dim soapUser As String
Dim soapPassword As String

Try
dom.Load(HttpStream)

' Reset the stream position.
HttpStream.Position = posStream

' Bind to the Authentication header.
soapUser = dom.GetElementsByTagName("User").Item(0).InnerText
soapPassword = dom.GetElementsByTagName("Password").Item(0).InnerText
Catch e As Exception
' Reset the position of stream.
HttpStream.Position = posStream

' Throw a SOAP exception.
Dim name As New XmlQualifiedName("Load")
Dim soapException As New SoapException("Unable to read SOAP request", name, e)
Throw soapException
End Try

' Raise the custom global.asax event.
OnAuthenticate(New WebServiceAuthenticationEvent(context, soapUser, soapPassword))
Return

End Sub 'OnEnter
End Class 'WebServiceAuthenticationModule

下面的代码示例是当接收到 SOAP 请求时,HTTP Module引发的自定义身份验证事件。

namespace Microsoft.WebServices.Security {
using System;
using System.Web;
using System.Security.Principal;

public class WebServiceAuthenticationEvent : EventArgs {
private Iprincipal _IPrincipalUser;
private HttpContext _Context;
private string _User;
private string _Password;

public WebServiceAuthenticationEvent(HttpContext context)
{
_Context = context;
}

public WebServiceAuthenticationEvent(HttpContext context,
string user, string password)
{
_Context = context;
_User = user;
_Password = password;
}
public  HttpContext Context
{
get { return _Context;}
}
public IPrincipal Principal
{
get { return _IPrincipalUser;}
set { _IPrincipalUser = value;}
}
public void Authenticate()
{
GenericIdentity i = new GenericIdentity(User);
this.Principal = new GenericPrincipal(i, new String[0]);
}
public void Authenticate(string[] roles)
{
GenericIdentity i = new GenericIdentity(User);
this.Principal = new GenericPrincipal(i, roles);
}
public string User
{
get { return _User; }
set { _User = value; }
}
public string Password
{
get { return _Password; }
set { _Password = value; }
}
public bool HasCredentials {
get
{
if ((_User == null) || (_Password == null))
return false;
return true;
}
}
}
}
Visual Basic 复制代码
Imports System
Imports System.Web
Imports System.Security.Principal

Public Class WebServiceAuthenticationEvent
Inherits EventArgs
Private _IPrincipalUser As Iprincipal
Private _Context As HttpContext
Private _User As String
Private _Password As String

Public Sub New(ByVal context As HttpContext)
_Context = context

End Sub 'New

Public Sub New(ByVal context As HttpContext, ByVal user As String, ByVal password As String)
_Context = context
_User = user
_Password = password

End Sub 'New

Public ReadOnly Property Context() As HttpContext
Get
Return _Context
End Get
End Property

Public Property Principal() As IPrincipal
Get
Return _IPrincipalUser
End Get
Set
_IPrincipalUser = value
End Set
End Property

Overloads Public Sub Authenticate()
Dim i As New GenericIdentity(User)
Me.Principal = New GenericPrincipal(i, New String(-1) {})

End Sub 'Authenticate

Overloads Public Sub Authenticate(ByVal roles() As String)
Dim i As New GenericIdentity(User)
Me.Principal = New GenericPrincipal(i, roles)

End Sub 'Authenticate

Public Property User() As String
Get
Return _User
End Get
Set
_User = value
End Set
End Property

Public Property Password() As String
Get
Return _Password
End Get
Set
_Password = value
End Set
End Property

Public ReadOnly Property HasCredentials() As Boolean
Get
If _User Is Nothing OrElse _Password Is Nothing Then
Return False
End If
Return True
End Get
End Property
End Class 'WebServiceAuthenticationEvent

下面的代码示例是自定义 WebServiceAuthenticationEvent 事件的委托。

C# 复制代码
namespace Microsoft.WebServices.Security
{
using System;

public delegate void WebServiceAuthenticationEventHandler(Object sender,  WebServiceAuthenticationEvent e);
}
Imports System

Public Delegate Sub WebServiceAuthenticationEventHandler(ByVal sender As [Object], ByVal e As WebServiceAuthenticationEvent)

下面的代码示例是一个 Web 服务,用于定义客户端必须传递的 Authentication SOAP 头。该 Web 服务不需要进行身份验证。相反,它可以检查 User.Identity.IsAuthenticated 属性,确定 HTTP Module是否已对用户进行了身份验证。

C# 复制代码
<%@ WebService Language="C#" Class="SecureWebService" %>

using System;
using System.Web.Services;
using System.Web.Services.Protocols;

public class Authentication : SoapHeader {
public string User;
public string Password;
}

public class SecureWebService : WebService{
public Authentication authentication;

[WebMethod]
[SoapHeader("authentication")]
public string ValidUser(){
if (User.IsInRole("Customer"))
return "User is in role customer";

if (User.Identity.IsAuthenticated)
return "User is a valid user";
return "not authenticated";
}
}
<%@ WebService Language="VB" Class="SecureWebService" %>

Imports System
Imports System.Web.Services
Imports System.Web.Services.Protocols

Public Class Authentication
Inherits SoapHeader
Public User As String
Public Password As String
End Class 'Authentication

Public Class SecureWebService
Inherits WebService
Public authentication As Authentication

<WebMethod(), SoapHeader("authentication")>  _
Public Function ValidUser() As String
If User.IsInRole("Customer") Then
Return "User is in role customer"
End If
If User.Identity.IsAuthenticated Then
Return "User is a valid user"
End If
Return "not authenticated"

End Function 'ValidUser
End Class 'SecureWebService

下面的代码示例是一个 Web 服务客户端,用于为 Authentication SOAP 头中的自定义 SOAP 头身份验证机制传递必要的凭据。

C# 复制代码
// Create a new instance of a Web service proxy class.
SecureWebService s = new SecureWebService();

// Create the Authentication SOAP header and set values.
Authentication a = new Authentication();
a.User = user.Value;
a.Password = password.Value;

// Assign the Header.
s.AuthenticationValue = a;

string result = s.ValidUser();
span1.InnerHtml = result;
' Create a new instance of a Web service proxy class.
Dim s As New SecureWebService()

' Create the Authentication SOAP header and set values.
Dim a As New Authentication()
a.User = user.Value
a.Password = password.Value

Assign the Header.
s.AuthenticationValue = a

Dim result As String = s.ValidUser()
span1.InnerHtml = result

转载于:https://www.cnblogs.com/caoxch/archive/2006/11/22/568313.html

  • 点赞
  • 收藏
  • 分享
  • 文章举报
aobc72208 发布了0 篇原创文章 · 获赞 0 · 访问量 280 私信 关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐