次の方法で共有


方法: データ サービス要求のクライアント資格情報を指定する (WCF Data Services)

既定では、OData サービスに要求を送信する際、クライアント ライブラリから資格情報は提供されません。ただし、DataServiceContextCredentials プロパティに NetworkCredential を設定することで、データ サービスへの要求を認証するために資格情報を送信するように指定できます。詳細については、「WCF Data Services のセキュリティ保護」を参照してください。このトピックの例では、データ サービスのデータを要求する際に WCF Data Services クライアントで使用する資格情報を明示的に提供する方法を示します。

このトピックの例では、Northwind サンプル データ サービスおよび自動生成されたクライアント データ サービス クラスを使用します。このサービスおよびクライアント データ クラスは、WCF Data Services クイック スタートを完了したときに作成されます。OData  Web サイトで公開されている Northwind サンプル データ サービスを使用することもできます。このサンプル データ サービスは読み取り専用で、変更を保存しようとするとエラーが返されます。OData  Web サイトのサンプル データ サービスでは、匿名認証が許可されます。

次の例は、Windows Presentation Framework アプリケーションのメイン ページである Extensible Application Markup Language (XAML) ファイルの分離コード ページからの抜粋です。この例では、LoginWindow インスタンスを表示してユーザーから認証資格情報を収集し、データ サービスへの要求を行うときにこれらの資格情報を使用します。

Imports NorthwindClient.Northwind
Imports System.Data.Services.Client
Imports System.Windows.Data
Imports System.Net
Imports System.Windows
Imports System.Security

Partial Public Class ClientCredentials
    Inherits Window

    ' Create the binding collections and the data service context.
    Private binding As DataServiceCollection(Of Customer)
    Private context As NorthwindEntities
    Private customerAddressViewSource As CollectionViewSource

    ' Instantiate the service URI and credentials.
    Dim serviceUri As Uri = New Uri("https://localhost:54321/Northwind.svc/")
    Private credentials As NetworkCredential = New NetworkCredential()

    Public Sub Main()
        InitializeComponent()
    End Sub

    Private Sub ClientCredentials_Loaded(ByVal sender As Object, ByVal e As RoutedEventArgs)

        Dim userName = String.Empty
        Dim domain = String.Empty
        Dim password = New SecureString()

        ' Get credentials for authentication.
        Dim login As New LoginWindow()
        login.ShowDialog()

        If login.DialogResult = True _
            AndAlso Not login.userNameBox.Text Is String.Empty _
            AndAlso login.passwordBox.SecurePassword.Length <> 0 Then

            ' Instantiate the context.
            context = New NorthwindEntities(serviceUri)

            ' Get the user name and domain from the login.
            Dim qualifiedUserName As String() = login.userNameBox.Text.Split(New [Char]() {"\"c})
            If qualifiedUserName.Length = 2 Then
                domain = qualifiedUserName(0)
                userName = qualifiedUserName(1)
            Else
                userName = login.userNameBox.Text
            End If
            password = login.passwordBox.SecurePassword

            ' Set the client authentication credentials.
            context.Credentials = _
                New NetworkCredential(userName, password, domain)


            ' Define an anonymous LINQ query that returns a collection of Customer types.
            Dim query = From c In context.Customers
                        Where c.Country = "Germany"
                        Select c

            Try
                ' Instantiate the binding collection, which executes the query.
                binding = New DataServiceCollection(Of Customer)(query)

                ' Load result pages into the binding collection.
                While Not binding.Continuation Is Nothing
                    ' Continue to execute the query until all pages are loaded.
                    binding.Load(context.Execute(Of Customer)(binding.Continuation.NextLinkUri))
                End While

                ' Assign the binding collection to the CollectionViewSource.
                customerAddressViewSource = _
                    CType(Me.Resources("customerViewSource"), CollectionViewSource)
                customerAddressViewSource.Source = binding
            Catch ex As Exception
                MessageBox.Show(ex.Message)
            End Try
        ElseIf login.DialogResult = False Then
            MessageBox.Show("Login cancelled.")
        End If
    End Sub
End Class
using System;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Security;
using NorthwindClient.Northwind;
using System.Data.Services.Client;

namespace NorthwindClient
{
    public partial class ClientCredentials : Window
    {
        // Create the binding collections and the data service context.
        private DataServiceCollection<Customer> binding;
        NorthwindEntities context;
        CollectionViewSource customerAddressViewSource;

        // Instantiate the service URI and credentials.
        Uri serviceUri = new Uri("https://localhost:12345/Northwind.svc/");
        NetworkCredential credentials = new NetworkCredential();

        public ClientCredentials()
        {
            InitializeComponent();
        }

        private void ClientCredentials_Loaded(object sender, RoutedEventArgs e)
        {
            string userName = string.Empty;
            string domain = string.Empty;
            SecureString password = new SecureString();

            // Get credentials for authentication.
            LoginWindow login = new LoginWindow();
            login.ShowDialog();

            if (login.DialogResult == true 
                && login.userNameBox.Text != string.Empty
                && login.passwordBox.SecurePassword.Length != 0)
            { 
                // Instantiate the context.
                context =
                    new NorthwindEntities(serviceUri);

                // Get the user name and domain from the login.
                string[] qualifiedUserName = login.userNameBox.Text.Split(new char[] { '\\' });
                if (qualifiedUserName.Length == 2)
                {
                    domain = qualifiedUserName[0];
                    userName = qualifiedUserName[1];
                }
                else
                {
                    userName = login.userNameBox.Text;
                }
                password = login.passwordBox.SecurePassword;

                // Set the client authentication credentials.
                context.Credentials =
                    new NetworkCredential(userName, password, domain);

               
                // Define an anonymous LINQ query that returns a collection of Customer types.
                var query = from c in context.Customers
                            where c.Country == "Germany"
                            select c;

                try
                {
                    // Instantiate the binding collection, which executes the query.
                    binding = new DataServiceCollection<Customer>(query);
         
                    while (binding.Continuation != null)
                    {
                        // Continue to execute the query until all pages are loaded.
                        binding.Load(context.Execute<Customer>(binding.Continuation.NextLinkUri));
                    }

                    // Assign the binding collection to the CollectionViewSource.
                    customerAddressViewSource =
                        (CollectionViewSource)this.Resources["customerViewSource"];
                    customerAddressViewSource.Source = binding;
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
            else if (login.DialogResult == false)
            {
                MessageBox.Show("Login cancelled.");
            }
        }
    }
}

次の XAML は、WPF アプリケーションのメイン ページを定義します。

    <Window x:Class="ClientCredentials"
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="https://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="https://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="312" d:DesignWidth="577" 
             Loaded="ClientCredentials_Loaded">
    <Window.Resources>
        <CollectionViewSource x:Key="customerViewSource" />
    </Window.Resources>
    <Grid x:Name="LayoutRoot" Background="White" DataContext="" Height="312" Width="577"
          VerticalAlignment="Top" HorizontalAlignment="Left">
        <Grid.RowDefinitions>
            <RowDefinition Height="203*" />
            <RowDefinition Height="119*" />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="336*" />
        </Grid.ColumnDefinitions>
        <DataGrid AutoGenerateColumns="False" Height="213" HorizontalAlignment="Left" 
                      ItemsSource="{Binding Source={StaticResource customerViewSource}}" 
                      Name="customerDataGrid" RowDetailsVisibilityMode="VisibleWhenSelected" 
                      VerticalAlignment="Top" Width="553" Margin="12,44,0,0" 
                      Grid.RowSpan="2" Grid.ColumnSpan="1">
            <DataGrid.Columns>
                <DataGridTextColumn x:Name="customerIDColumn" Binding="{Binding Path=CustomerID}" 
                                        Header="Customer" Width="80" />
                <DataGridTextColumn x:Name="addressColumn" Binding="{Binding Path=Address}" 
                                        Header="Address" Width="180" />
                <DataGridTextColumn x:Name="cityColumn" Binding="{Binding Path=City}" 
                                        Header="City" Width="120" />
                <DataGridTextColumn x:Name="countryColumn" Binding="{Binding Path=Country}" 
                                        Header="Country" Width="80" />
                <DataGridTextColumn x:Name="postalCodeColumn" Binding="{Binding Path=PostalCode}" 
                                        Header="Postal Code" Width="90" />
                <DataGridTextColumn Binding="{Binding Path=CompanyName}" Header="CompanyName" />
                <DataGridTextColumn Binding="{Binding Path=ContactName}" Header="ContactName" />
                <DataGridTextColumn Binding="{Binding Path=Phone}" Header="Phone" />
            </DataGrid.Columns>
        </DataGrid>
        <Label Grid.Row="0" Grid.Column="0" Height="26" HorizontalAlignment="Left" Margin="16,12,0,0" 
                   Name="serviceUriLabel" VerticalAlignment="Top" Width="550"  />
    </Grid>
</Window>

次の例は、データ サービスへの要求を行う前にユーザーから認証資格情報を収集するために使用するウィンドウの分離コード ページからの抜粋です。

Imports System.ComponentModel
Imports System.Windows
Imports System.Security

Partial Public Class LoginWindow
    Inherits Window

    Public Sub New()
        InitializeComponent()
    End Sub

    Private Sub OKButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs) Handles OKButton.Click
        Me.DialogResult = True
        e.Handled = True
    End Sub

    Private Sub CancelButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs) Handles CancelButton.Click
        Me.DialogResult = False
        e.Handled = True
    End Sub

    Private Sub LoginWindow_Closing(ByVal sender As System.Object, ByVal e As CancelEventArgs)
        If Me.DialogResult = True AndAlso _
                    (Me.userNameBox.Text = String.Empty OrElse Me.passwordBox.SecurePassword.Length = 0) Then
            e.Cancel = True
            MessageBox.Show("Please enter name and password or click Cancel.")
        End If
    End Sub
End Class
using System;
using System.Windows;
using System.Windows.Controls;
using System.ComponentModel;

namespace NorthwindClient
{
    public partial class LoginWindow : Window
    {
        public LoginWindow()
        {
            InitializeComponent();
        }

        private void OKButton_Click(object sender, RoutedEventArgs e)
        {
            this.DialogResult = true;
            e.Handled = true;
        }

        private void CancelButton_Click(object sender, RoutedEventArgs e)
        {
             this.DialogResult = false;
             e.Handled = true;
        }

        private void LoginWindow_Closing(object sender, CancelEventArgs e)
        {
            if (this.DialogResult == true &&
                    (this.userNameBox.Text == string.Empty || this.passwordBox.SecurePassword.Length == 0))
            {
                e.Cancel = true;
                MessageBox.Show("Please enter name and password or click Cancel.");
            }
        }

    }
}

次の XAML は、WPF アプリケーションのログインを定義します。

    <Window x:Class="LoginWindow"
           xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation" 
           xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml" 
           Width="400" Height="200" 
           Title="LoginWindow" xmlns:sdk="https://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk" Closing="LoginWindow_Closing">
    <StackPanel Name="LayoutRoot" Orientation="Vertical" VerticalAlignment="Top">
        <StackPanel Orientation="Horizontal">
            <TextBlock Height="25" HorizontalAlignment="Left" Margin="10,20,0,0" Name="userNameLabel" VerticalAlignment="Top" 
                       Width="80" Text="User name:"/>
            <TextBox Height="23" HorizontalAlignment="Left" Margin="10,20,0,0"  Name="userNameBox" VerticalAlignment="Top" 
                     Width="150" Text="DOMAIN\login"/>
        </StackPanel>
        <StackPanel Orientation="Horizontal" VerticalAlignment="Top">
            <TextBlock Height="25" HorizontalAlignment="Left" Margin="10,20,0,0" Name="pwdLabel" Width="80" Text="Password:"/>
            <PasswordBox Height="23" HorizontalAlignment="Left" Margin="10,20,0,0" Name="passwordBox" Width="150" />
        </StackPanel>
        <StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Height="80" VerticalAlignment="Top">
            <Button x:Name="CancelButton" Content="Cancel" Click="CancelButton_Click" Width="75" Height="23" 
                HorizontalAlignment="Right" Margin="8" IsCancel="True" />
            <Button x:Name="OKButton" Content="OK" Click="OKButton_Click" Width="75" Height="23" 
                HorizontalAlignment="Right" Margin="8" IsDefault="True" />
        </StackPanel>
    </StackPanel>
</Window>

セキュリティ

このトピックの例には、以下のセキュリティに関する注意点があります。

  • このサンプルで指定した資格情報が機能することを確認するには、Northwind データ サービスで匿名アクセス以外の認証方式を使用する必要があります。そうしない場合、データ サービスをホストする Web サイトが資格情報を要求しません。

  • ユーザー資格情報は実行時にのみ要求し、キャッシュしないようにする必要があります。資格情報は常に安全に格納する必要があります。

  • 基本認証およびダイジェスト認証で送信されるデータは暗号化されないため、敵対者がデータを見ることができます。また、基本認証の資格情報 (ユーザー名とパスワード) はクリア テキストで送信されるので、傍受される可能性があります。

詳細については、「WCF Data Services のセキュリティ保護」を参照してください。

参照

概念

WCF Data Services のセキュリティ保護

その他のリソース

WCF Data Services クライアント ライブラリ