我的问题类似于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;
}
答案 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(除了删除本地创建用户链接)。