2

我在看一些在後端使用WCF RIA和Entity Framework的Silverlight應用程序。是由Visual Studio生成的代碼是WCF RIA和實體框架的安全性如何?

public IQueryable<someEntity> GetSomeEntity() 
{ 
    return this.ObjectContext.someEntity; 
} 

現在,假設我放下了正確的身份驗證,以便只有經過驗證的用戶可以調用這個Web服務。我還在Sliverlight客戶端上擁有用戶訪問控制權,以便他們只能訪問允許訪問的數據。什麼是阻止認證用戶僞造Web服務請求(即繞過Silverlight客戶端的訪問控制),而不是實現Web服務本身的訪問控制?

回答

1

這是完整的解決方案如何使用Silverlight保護RIA服務。我希望它能幫助你。

Web項目

編寫自定義成員提供

public class CustomMembershipProvider : MembershipProvider 
{ 
    public override bool ValidateUser(string username, string password) 
    { 
     using(Model.YourDomainModel context = new Model.YourDomainModel()) 
     { 
      var usr = context.Users.Where(u => u.Login == username && 
       u.Password == password).FirstOrDefault(); 

      return usr != null; 
     } 
    } 

    public override string ApplicationName 
    { 
     get 
     { 
      return "Your app name"; 
     } 
     set 
     { 
      throw new NotImplementedException(); 
     } 
    } 

    // Other overrides not implemented 
    #region Other overrides not implemented 
    public override bool ChangePassword(string username, string oldPassword, string newPassword) 
    { 
     throw new NotImplementedException(); 
    } 

    public override bool ChangePasswordQuestionAndAnswer(string username, string password, string newPasswordQuestion, string newPasswordAnswer) 
    { 
     throw new NotImplementedException(); 
    } 

    public override MembershipUser CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, out MembershipCreateStatus status) 
    { 
     throw new NotImplementedException(); 
    } 

    public override bool DeleteUser(string username, bool deleteAllRelatedData) 
    { 
     throw new NotImplementedException(); 
    } 

    public override bool EnablePasswordReset 
    { 
     get { throw new NotImplementedException(); } 
    } 

    public override bool EnablePasswordRetrieval 
    { 
     get { throw new NotImplementedException(); } 
    } 

    public override MembershipUserCollection FindUsersByEmail(string emailToMatch, int pageIndex, int pageSize, out int totalRecords) 
    { 
     throw new NotImplementedException(); 
    } 

    public override MembershipUserCollection FindUsersByName(string usernameToMatch, int pageIndex, int pageSize, out int totalRecords) 
    { 
     throw new NotImplementedException(); 
    } 

    public override MembershipUserCollection GetAllUsers(int pageIndex, int pageSize, out int totalRecords) 
    { 
     throw new NotImplementedException(); 
    } 

    public override int GetNumberOfUsersOnline() 
    { 
     throw new NotImplementedException(); 
    } 

    public override string GetPassword(string username, string answer) 
    { 
     throw new NotImplementedException(); 
    } 

    public override MembershipUser GetUser(string username, bool userIsOnline) 
    { 
     throw new NotImplementedException(); 
    } 

    public override MembershipUser GetUser(object providerUserKey, bool userIsOnline) 
    { 
     throw new NotImplementedException(); 
    } 

    public override string GetUserNameByEmail(string email) 
    { 
     throw new NotImplementedException(); 
    } 

    public override int MaxInvalidPasswordAttempts 
    { 
     get { throw new NotImplementedException(); } 
    } 

    public override int MinRequiredNonAlphanumericCharacters 
    { 
     get { throw new NotImplementedException(); } 
    } 

    public override int MinRequiredPasswordLength 
    { 
     get { throw new NotImplementedException(); } 
    } 

    public override int PasswordAttemptWindow 
    { 
     get { throw new NotImplementedException(); } 
    } 

    public override MembershipPasswordFormat PasswordFormat 
    { 
     get { throw new NotImplementedException(); } 
    } 

    public override string PasswordStrengthRegularExpression 
    { 
     get { throw new NotImplementedException(); } 
    } 

    public override bool RequiresQuestionAndAnswer 
    { 
     get { throw new NotImplementedException(); } 
    } 

    public override bool RequiresUniqueEmail 
    { 
     get { throw new NotImplementedException(); } 
    } 

    public override string ResetPassword(string username, string answer) 
    { 
     throw new NotImplementedException(); 
    } 

    public override bool UnlockUser(string userName) 
    { 
     throw new NotImplementedException(); 
    } 

    public override void UpdateUser(MembershipUser user) 
    { 
     throw new NotImplementedException(); 
    } 
    #endregion 

編寫自定義角色提供

public class CustomRoleProvider : RoleProvider 
{ 
    public override string[] GetRolesForUser(string username) 
    { 
     using(Model.YourDomainModel context = new Model.YourDomainModel()) 
     { 
      string[] roles = (from r in Roles 
          where r.User_name == username 
          select r.Role).ToArray(); 
      return roles; 
     } 
    } 

    public override string ApplicationName 
    { 
     get 
     { 
      return "Your app name"; 
     } 
     set 
     { 
      throw new NotImplementedException(); 
     } 
    } 

    //Other overrides not implemented 
    #region Other overrides not implemented 
    public override void AddUsersToRoles(string[] usernames, string[] roleNames) 
    { 
     throw new NotImplementedException(); 
    } 

    public override void CreateRole(string roleName) 
    { 
     throw new NotImplementedException(); 
    } 

    public override bool DeleteRole(string roleName, bool throwOnPopulatedRole) 
    { 
     throw new NotImplementedException(); 
    } 

    public override string[] FindUsersInRole(string roleName, string usernameToMatch) 
    { 
     throw new NotImplementedException(); 
    }  

    public override string[] GetAllRoles() 
    { 
     throw new NotImplementedException(); 
    } 

    public override string[] GetUsersInRole(string roleName) 
    { 
     throw new NotImplementedException(); 
    } 

    public override bool IsUserInRole(string username, string roleName) 
    { 
     throw new NotImplementedException(); 
    } 

    public override void RemoveUsersFromRoles(string[] usernames, string[] roleNames) 
    { 
     throw new NotImplementedException(); 
    } 

    public override bool RoleExists(string roleName) 
    { 
     throw new NotImplementedException(); 
    } 
    #endregion 
} 

撰寫您AuthenticationDomainService類

[EnableClientAccess] 
public class YourAuthenticationDomainService : AuthenticationBase<AuthUser> 
{ 
} 

public class AuthUser : UserBase 
{ 
} 

添加EnableClientAcces到你的DomainService和檢查的作用

[EnableClientAccess()] 
public class YourDomainService : DomainService 
{ 
    public YourDomainService() 
     : base() 
    { 
    } 


    [RequiresRole("Role1, Role2")] 
    public IQueryable<someEntity> GetSomeEntity() 
    { 
     return this.ObjectContext.someEntity; 
    } 
} 

在Web.Config中添加:

<system.web> 
    <authentication mode="Forms" /> 

    <membership defaultProvider="MyCustomProvider"> 
     <providers> 
      <add name="MyCustomProvider" type="MyProject.Web.CustomMembershipProvider,MyProject.Web" /> 
     </providers> 
    </membership> 

    <roleManager enabled="true" defaultProvider="MyCustomProvider"> 
     <providers> 
      <add name="MyCustomProvider" type="MyProject.Web.CustomRoleProvider,MyProject.Web" /> 
     </providers> 
    </roleManager> 
</system.web> 

SILVERLIGHT

在App.xaml.cs添加WebContext到ApplicationLifetimeObjects

public partial class App : Application 
{ 
    public App() 
    { 
     InitializeComponent(); 

     WebContext context = new WebContext(); 
     context.Authentication = new FormsAuthentication(); 
     ApplicationLifetimeObjects.Add(context); 
    } 
} 

寫下您的登錄電子表單/對話框像

LoginDialog.xaml

<Grid x:Name="LayoutRoot" Margin="2"> 
    <Grid.RowDefinitions> 
     <RowDefinition Height="Auto" /> 
     <RowDefinition Height="Auto" /> 
     <RowDefinition Height="Auto" /> 
    </Grid.RowDefinitions> 
    <Grid.ColumnDefinitions> 
     <ColumnDefinition Width="Auto" /> 
     <ColumnDefinition /> 
    </Grid.ColumnDefinitions> 

    <TextBlock Grid.Column="0" Grid.Row="0" Text="Login:" /> 
    <TextBlock Grid.Column="0" Grid.Row="0" Text="Password:" /> 
    <TextBox x:Name="txtLogin" Grid.Column="1" Grid.Row="0" /> 
    <PasswordBox x:Name="txtPassword" Grid.Column="1" Grid.Row="1" /> 
    <Button x:Name="btnLogin" Click="btnLogin_Click" Grid.Column="1" Grid.Row="2" /> 
</Grid> 

LoginDialog.xaml.cs

private void btnLogin_Click((object sender, RoutedEventArgs e)) 
{ 
    LoginOperation loginOp = WebContext.Current.Authentication.Login(
     new LoginParameters(txtLogin.Text, txtPassword.Password)); 
    loginOp.Completed += (s2, e2) => 
    { 
     if (loginOp.HasError) 
     { 
      //HANDLE ERROR 
      loginOp.MarkErrorAsHandled(); 
     } 
     else if (!loginOp.LoginSuccess) 
     { 
      MessageBox.Show("Wrong login or password."); 
     } 
     else 
     { 
      DialogResult = true; 
     } 
    }; 
}