2

Je regardais une application Silverlight qui utilise WCF RIA et Entity Framework dans le backend. Le code généré par Visual Studio estQuelle est la sécurité de WCF RIA et Entity Framework?

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

Maintenant, supposons que je posai l'authentification correcte afin que seul utilisateur authentifié peut appeler ce service Web. J'ai également un contrôle d'accès utilisateur sur le client Sliverlight afin qu'ils puissent uniquement accéder aux données auxquelles ils sont autorisés. Qu'est-ce qui empêche un utilisateur authentifié de forger une demande de service Web (c'est-à-dire en contournant le contrôle d'accès sur le client Silverlight) autre que la mise en œuvre du contrôle d'accès sur le service Web lui-même?

Répondre

1

Voici une solution complète pour sécuriser le service RIA avec Silverlight. J'espère que ça t'aide.

PROJET WEB

Ecrire sur mesure fournisseur d'appartenances

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 

fournisseur de rôles écriture personnalisée

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 
} 

Écrivez votre classe AuthenticationDomainService

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

public class AuthUser : UserBase 
{ 
} 

Ajouter à votre EnableClientAcces DomainService et vérifier les rôles

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


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

dans web.config ajouter:

<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

En App.xaml.cs ajouter WebContext à ApplicationLifetimeObjects

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

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

Écrivez votre formulaire loging/dialogue comme

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; 
     } 
    }; 
}