在RIA域服务上遇到RequiresRole属性问题

时间:2011-03-08 19:05:25

标签: silverlight wcf-ria-services

我的问题类似于question。我希望我能提供更多的细节和背景来解决问题。

所以这里有一些背景:我有一个简单的内部Silverlight(ver 4)应用程序,我正在为我们的小型支持团队建立WCF Ria服务。它使用针对第三方销售数据库的身份验证,但使用所有其他用户信息,例如FriendlyName和Roles(每个用户只有1个角色)来自我们自己的数据库。我试图保持这个简单,不想实现自定义成员资格和角色提供者。

我想要限制某些角色的域服务操作很少,所以我尝试使用RequiresRole属性,如下所示:

[RequiresRole("Admin", "HelpDesk", "Billing" )]
public RisStudyInfo GetStudyInfo(string accession) {
    return ris.GetStudyInfo(accession);
}

在客户端WebContext.Current.User.IsInRole("Admin")返回true,但在调用服务时我总是被拒绝访问。 RequiresAuthentication属性按预期工作。

以下是我AuthenticationService的实施情况。 User类只是继承自UserBase并添加FriendlyName属性。我有什么想法吗?

[EnableClientAccess]
public class AuthenticationService : AuthenticationBase<User> {

    UserDataService userData = new UserDataService();

    protected override bool ValidateUser(string userName, string password) {
        var auth = new DatabaseAuthenticator();
        return auth.Authenticate(userName, password);
    }

    protected override User GetAuthenticatedUser(IPrincipal principal) {
        User user = null;
        if (principal.Identity.IsAuthenticated) {
            user = new User();
            user.FriendlyName = userData.GetFriendlyName(principal.Identity.Name);
            user.Name = principal.Identity.Name;
            user.Roles = GetRolesFor(user.Name);
        }
        return user;
    }

    private IEnumerable<string> GetRolesFor(string username) {

        IList<string> roles = new List<string>();

        string role = userData.GetRolesFor(username);
        if (role != null)
            roles.Add(role);

        return roles;
    }

2 个答案:

答案 0 :(得分:1)

想出来。至少2件事错了。第一条线索发现here。第二条线索here

1.Turns out我确实需要编写自定义角色提供程序。只需要实现GetRolesForUser

public override string[] GetRolesForUser(string username) {
   return new string[] { _userService.GetRolesFor(username) };
}    

2.在web.config

中正确配置自定义角色提供程序
<roleManager cacheRolesInCookie="true" enabled="true" defaultProvider="MyRoleProvider">
    <providers>
      <add name="MyRoleProvider" type="MyProject.Web.Providers.MyRoleProvider, MyProject.Web"/>
    </providers>
</roleManager>

答案 1 :(得分:0)

我通过使用本地凭据存储来缓存凭据来解决这个问题。每当本地信用检查失败时,就会发生外部检查并填充/更新缓存。这是ValidateUser方法的一个简单的重写。这确实意味着过时的密码会继续有效,直到使用更新的密码(它将在本地失败,远程传递并触发更新)。

这种方法意味着内部一切都按照开箱即用的配置工作,不需要任何其他mod(除了删除本地创建用户链接)。