Open Data Protocol (OData) を実装するデータ サービスへの要求を行うときに使用する資格情報を指定できます。 指定するには、ドメイン間要求を行う、ブラウザー外で実行する、または HttpStack プロパティの値を明示的に ClientHttp に設定する必要があります。 この場合、資格情報キャッシュの既定の資格情報が使用されます。 また、UseDefaultCredentials プロパティを false に設定し、DataServiceContext の Credentials プロパティに NetworkCredential を設定することで、既定以外の資格情報を指定することもできます。 このトピックの例では、データ サービスのデータを要求する際に Silverlight クライアントで使用する資格情報を明示的に提供する方法を示します。
WCF Data Services クイック スタートの完了時に、アプリケーションがアクセスする Northwind サンプル データ サービスが作成されます。 OData Web サイトで公開されている Northwind サンプル データ サービスを使用することもできます。このサンプル データ サービスは読み取り専用で、変更内容を保存しようとするとエラーが返されます。
使用例
次の例は、Silverlight アプリケーションのメイン ページである Extensible Application Markup Language (XAML) ファイルの分離コード ページからの抜粋です。 この例では、LoginWindow インスタンスを表示してユーザーから認証資格情報を収集します。次に、Silverlight クライアントの HTTP 実装を使用してデータ サービスへの要求を行うときにこれらの既定以外の資格情報を使用します。
Imports ClientCredentials.Northwind
Imports System.Data.Services.Client
Imports System.Windows.Data
Imports System.Net
Partial Public Class MainPage
Inherits UserControl
' 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 MainPage_Loaded(ByVal sender As Object, ByVal e As RoutedEventArgs)
' Get credentials for authentication.
Dim login As LoginWindow = New LoginWindow()
AddHandler login.Closed, AddressOf loginWindow_Closed
login.Show()
End Sub
Private Sub loginWindow_Closed(ByVal sender As Object, ByVal e As EventArgs)
Dim userName = String.Empty
Dim domain = String.Empty
Dim password = String.Empty
' Get back the LoginWindow instance.
Dim login As LoginWindow = CType(sender, LoginWindow)
If login.DialogResult = True AndAlso Not login.userNameBox.Text Is String.Empty Then
' Instantiate the binding collection.
binding = New DataServiceCollection(Of Customer)()
' Instantiate the context.
context = New NorthwindEntities(serviceUri)
' Register the LoadCompleted event for the binding collection.
AddHandler binding.LoadCompleted, AddressOf binding_LoadCompleted
' 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
' 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.Password
' Select the client HTTP stack and set the credentials.
context.HttpStack = HttpStack.ClientHttp
context.UseDefaultCredentials = False
context.Credentials = _
New NetworkCredential(userName, password, domain)
Try
' Execute the query asynchronously.
binding.LoadAsync(query)
Catch ex As Exception
Dim cw = New ChildWindow()
cw.Content = ex.Message
cw.Show()
End Try
ElseIf login.DialogResult = False Then
Dim cw = New ChildWindow()
cw.Content = "Login cancelled."
cw.Show()
End If
End Sub
Private Sub binding_LoadCompleted(ByVal sender As Object, ByVal e As LoadCompletedEventArgs)
If e.Error Is Nothing Then
serviceUriLabel.Content = serviceUri.ToString()
' Load all pages of Customers before binding.
If Not binding.Continuation Is Nothing Then
binding.LoadNextPartialSetAsync()
Else
' Load your data here and assign the result to the CollectionViewSource.
customerAddressViewSource = _
CType(Me.Resources("customerViewSource"), CollectionViewSource)
customerAddressViewSource.Source = binding
End If
Else
' Display the error message from the data service.
Dim cw = New ChildWindow()
cw.Content = e.Error.Message
cw.Show()
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 ClientCredentials.Northwind;
using System.Data.Services.Client;
namespace ClientCredentials
{
public partial class MainPage : UserControl
{
// 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 MainPage()
{
InitializeComponent();
}
private void MainPage_Loaded(object sender, RoutedEventArgs e)
{
// Get credentials for authentication.
LoginWindow login = new LoginWindow();
login.Closed += new EventHandler(loginWindow_Closed);
login.Show();
}
private void loginWindow_Closed(object sender, EventArgs e)
{
string userName = string.Empty;
string domain = string.Empty;
string password = string.Empty;
// Get back the LoginWindow instance.
LoginWindow login = (LoginWindow)sender;
if (login.DialogResult == true && login.userNameBox.Text != string.Empty)
{
// Instantiate the binding collection.
binding = new DataServiceCollection<Customer>();
// Instantiate the context.
context =
new NorthwindEntities(serviceUri);
// Register the LoadCompleted event for the binding collection.
binding.LoadCompleted += new EventHandler<LoadCompletedEventArgs>(binding_LoadCompleted);
// 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;
// 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.Password;
// Select the client HTTP stack and set the credentials.
context.HttpStack = HttpStack.ClientHttp;
context.UseDefaultCredentials = false;
context.Credentials =
new NetworkCredential(userName, password, domain);
try
{
// Execute the query asynchronously.
binding.LoadAsync(query);
}
catch (Exception ex)
{
ChildWindow cw = new ChildWindow();
cw.Content = ex.Message;
cw.Show();
}
}
else if (login.DialogResult == false)
{
ChildWindow cw = new ChildWindow();
cw.Content = "Login cancelled.";
cw.Show();
}
}
private void binding_LoadCompleted(object sender, LoadCompletedEventArgs e)
{
if (e.Error == null)
{
serviceUriLabel.Content = serviceUri.ToString();
// Load all pages of Customers before binding.
if (binding.Continuation != null)
{
binding.LoadNextPartialSetAsync();
}
else
{
// Load your data here and assign the result to the CollectionViewSource.
customerAddressViewSource =
(CollectionViewSource)this.Resources["customerViewSource"];
customerAddressViewSource.Source = binding;
}
}
else
{
// Display the error message from the data service.
ChildWindow cw = new ChildWindow();
cw.Content = e.Error.Message;
cw.Show();
}
}
}
}
次の XAML は、Silverlight アプリケーションのメイン ページを定義します。
<UserControl x:Class="ClientCredentials.MainPage"
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"
xmlns:sdk="https://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"
xmlns:my="clr-namespace:ClientCredentials" Loaded="MainPage_Loaded">
<UserControl.Resources>
<CollectionViewSource x:Key="customerViewSource"
d:DesignSource="{d:DesignInstance my:Northwind.Customer, CreateList=True}" />
</UserControl.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>
<sdk: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">
<sdk:DataGrid.Columns>
<sdk:DataGridTextColumn x:Name="customerIDColumn" Binding="{Binding Path=CustomerID}"
Header="Customer" Width="80" />
<sdk:DataGridTextColumn x:Name="addressColumn" Binding="{Binding Path=Address}"
Header="Address" Width="180" />
<sdk:DataGridTextColumn x:Name="cityColumn" Binding="{Binding Path=City}"
Header="City" Width="120" />
<sdk:DataGridTextColumn x:Name="countryColumn" Binding="{Binding Path=Country}"
Header="Country" Width="80" />
<sdk:DataGridTextColumn x:Name="postalCodeColumn" Binding="{Binding Path=PostalCode}"
Header="Postal Code" Width="90" />
<sdk:DataGridTextColumn Binding="{Binding Path=CompanyName}" Header="CompanyName" />
<sdk:DataGridTextColumn Binding="{Binding Path=ContactName}" Header="ContactName" />
<sdk:DataGridTextColumn Binding="{Binding Path=Phone}" Header="Phone" />
</sdk:DataGrid.Columns>
</sdk:DataGrid>
<sdk:Label Grid.Row="0" Grid.Column="0" Height="26" HorizontalAlignment="Left" Margin="16,12,0,0"
Name="serviceUriLabel" VerticalAlignment="Top" Width="550" />
</Grid>
</UserControl>
次の例は、データ サービスへの要求を行う前にユーザーから認証資格情報を収集するために使用する ChildWindow の分離コード ページからの抜粋です。
Imports System.ComponentModel
Partial Public Class LoginWindow
Inherits ChildWindow
Public Sub New()
InitializeComponent()
End Sub
Private Sub OKButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs) Handles OKButton.Click
Me.DialogResult = True
End Sub
Private Sub CancelButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs) Handles CancelButton.Click
Me.DialogResult = False
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.Password = String.Empty) Then
e.Cancel = True
Dim cw As ChildWindow = New ChildWindow()
cw.Content = "Please enter name and password or click Cancel."
cw.Show()
End If
End Sub
End Class
using System;
using System.Windows;
using System.Windows.Controls;
using System.ComponentModel;
namespace ClientCredentials
{
public partial class LoginWindow : ChildWindow
{
public LoginWindow()
{
InitializeComponent();
}
private void OKButton_Click(object sender, RoutedEventArgs e)
{
this.DialogResult = true;
}
private void CancelButton_Click(object sender, RoutedEventArgs e)
{
this.DialogResult = false;
}
private void LoginWindow_Closing(object sender, CancelEventArgs e)
{
if (this.DialogResult == true &&
(this.userNameBox.Text == string.Empty || this.passwordBox.Password == string.Empty))
{
e.Cancel = true;
ChildWindow cw = new ChildWindow();
cw.Content = "Please enter name and password or click Cancel.";
cw.Show();
}
}
}
}
次の XAML は、Silverlight アプリケーションの ChildWindow であるログイン ウィンドウを定義します。
<controls:ChildWindow x:Class="ClientCredentials.LoginWindow"
xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls"
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" />
<Button x:Name="OKButton" Content="OK" Click="OKButton_Click" Width="75" Height="23"
HorizontalAlignment="Right" Margin="8" />
</StackPanel>
</StackPanel>
</controls:ChildWindow>
セキュリティ
このトピックの例には、以下のセキュリティに関する注意点があります。
このサンプルで指定した資格情報が機能することを確認するには、Northwind データ サービスで匿名アクセス以外の認証方式を使用する必要があります。 そうしない場合、データ サービスをホストする Web サイトが資格情報を要求しません。
ユーザー資格情報は実行時にのみ要求し、キャッシュしないようにする必要があります。 資格情報は常に安全に格納する必要があります。
基本認証およびダイジェスト認証で送信されるデータは暗号化されないため、敵対者がデータを見ることができます。 また、基本認証の資格情報 (ユーザー名とパスワード) はクリア テキストで送信されるので、傍受される可能性があります。
関連項目
概念
Silverlight アプリケーションの作成 (WCF Data Services)