方法 : SOAP ヘッダーを使用してカスタム認証を実行する
ASP.NET を使用して作成した次のカスタム ソリューションには、SOAP ヘッダーを使用する認証機構が備わっています。このソリューションには、次の手順を実行する Web サーバー上のカスタムな IHttpModule が含まれています。
HTTP Module が HTTP メッセージを解析し、SOAP メッセージかどうかをチェックします。
HTTP Module が SOAP メッセージを検出すると、SOAP ヘッダーが読み取られます。
SOAP メッセージの SOAP ヘッダーに認証資格情報が含まれている場合、HTTP Module は、カスタムな global.asax イベントを発生させます。
ここで紹介する例では、HTTP Module でユーザーを認証し、Context プロパティを設定します。Web サービスでは、これらのプロパティを使用して、Web サービスへのアクセスを承認されたクライアントかどうかを判断します。
メモ : |
---|
この例では、テキストがクリアな (暗号化されない) テキストとして、ネットワーク経由で送信されます。クリア テキストではアプリケーションのセキュリティが不十分な場合は、暗号化アルゴリズムを追加してください。 |
例
SOAP 要求に対して HTTP メッセージを解析する HTTP モジュールのコード例を次に示します。HTTP メッセージが SOAP メッセージである場合、カスタムな WebServiceAuthenticationEvent
が生成されます。
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;
}
}
}
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;
}
}
}
}
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
イベント用のデリゲートのコード例です。
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)
次に示すのは、クライアントが渡す必要のある Authentication
SOAP ヘッダーを定義する Web サービスのコード例です。Web サービスでは認証を行う必要はありません。代わりに、User.Identity.IsAuthenticated プロパティを確認して、HTTP Module がユーザーを認証したかどうかを判断できます。
<%@ 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
次に示すのは、Authentication
SOAP ヘッダー内のカスタム SOAP ヘッダー認証機構に必要な資格情報を渡す Web サービス クライアントのコード例です。
// 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
関連項目
タスク
方法 : Windows 認証用に XML Web サービスを構成する
参照
NetworkCredential
CredentialCache
X509Certificate
概念
ASP.NET を使用して作成した XML Web サービスのセキュリティ
その他の技術情報
Securing ASP.NET Web Applications
ASP.NET を使用した XML Web サービス
Copyright © 2007 by Microsoft Corporation.All rights reserved.