Reputation: 31
I've looked at several examples of ServiceStack's Authentication/Authorization code but I can't seem to get past this issue.
I have created a custom AuthFeature
which derives from BasicAuthProvider
and registered it in the plugins on my AppHost. In my custom provider I overrode TryAuthenticate
and OnAuthenticated
and on my service I have decorated the class with attributes for [Authenticate]
and [RequiresAnyRole("Test")]
. In my use case, I pass a username and password in my Auth header hitting my service, which calls TryAuthenticate
(and passes authentication), then hits the OnAuthenticated
method which I fill the session variable with a role (in this case "Test"). The result is a 403 Invalid Role
. If I remove the RequiresAnyRole
attribute the authentication works, and I can even look at the current session variable and see my role that I created. Additionally I have tried RequiredRole
and RequiredPermission
(by adding a permission to the session as well) with the same result.
Can someone tell me if I am properly adding the session with my test role correctly, or if I have implemented the custom auth provider correctly?
My auth provider code:
public class AdAuthProvider : BasicAuthProvider
{
public override bool TryAuthenticate(IServiceBase authService, string userName, string password)
{
var authenticated = false;
UserPrincipal userPrincipal = UserPrincipal.FindByIdentity(new PrincipalContext(ContextType.Domain), userName);
var adRealm = System.Configuration.ConfigurationManager.AppSettings["ADRealm"];
if (userPrincipal != null)
{
using (var pc = new PrincipalContext(ContextType.Domain, adRealm))
{
authenticated = pc.ValidateCredentials(userName, password);
}
}
return authenticated;
}
public override IHttpResult OnAuthenticated(IServiceBase authService, IAuthSession session, IAuthTokens tokens, Dictionary<string, string> authInfo)
{
session.Roles = new List<string>();
session.Roles.Add("Test");
authService.SaveSession(session, new System.TimeSpan(0, 30, 0));
return null;
}
My service code:
[Authenticate]
[RequiresAnyRole("Test")]
public class TestService: Service
{
...
Upvotes: 3
Views: 293
Reputation: 2322
You'll need to use use the AuthRepository
to AssignRole
rather than using the session object which doesn't persist.
Have a look at the assignrole
service code on GitHub to see how to resolve your authRepo
and assign the role.
var authRepo = HostContext.AppHost.GetAuthRepository(base.Request);
using (authRepo as IDisposable)
{
var userAuth = authRepo.GetUserAuthByUserName(request.UserName);
if (userAuth == null)
throw HttpError.NotFound(request.UserName);
authRepo.AssignRoles(userAuth, request.Roles, request.Permissions);
https://github.com/ServiceStack/ServiceStack/blob/master/src/ServiceStack/Auth/AssignRolesService.cs
Upvotes: 2