3

I've created a custom API Controller that inherits from ServicesApiController. I've created also custom route and it all works fine.

Something like the following:

public class ExampleController : ServicesApiController
{
    public ActionResult Index()
    {
        return null;
    }
}

However I want to ensure that this is secured and doesn't expose my list of items to unauthorized users.

I was thinking of applying the same requirements as the ItemService and requiring use of the auth/login endpoint before requests can be made to my custom controller.

However after digging into the code for the ItemService with DotPeek I can't seem to find how this is implemented for the ItemService.

I thought it would be using a custom filter that checks whether user is authenticated.

I've read over the docs here:

https://doc.sitecore.net/sitecore_experience_platform/developing/developing_with_sitecore/sitecoreservicesclient/sitecoreservicesclient_security?roles=developer

And it says:

Sitecore.Services.Client provides two layers of security:

  • A security policy that applies to all Sitecore.Services.Client requests.
  • Individual filters that can add additional requirements on requests that are to be executed.

So this also suggests that.

I'd appreciate any guidance on if there is a filter I can use to require login or if I need to create my own that does something like:

public override void OnAuthorization(HttpActionContext actionContext)
{
   if (Context.User.IsAuthenticated){
       return;
   }
   actionContext.Response = actionContext.ControllerContext.Request.CreateErrorResponse(HttpStatusCode.Unauthorized, "Unauthorized Access");
   base.OnAuthorization(actionContext);
}

Or is there a better way to do this?

Other Info: Sitecore 8.2. Update 6

0

2 Answers 2

1

I would go with custom Authentication/Authorization Filter:

public class AuthorizedUser : AuthorizationFilterAttribute
    {
        private readonly string _user;

        public AuthorizedUser(string user)
        {
            _user = user;
        }
        public override void OnAuthorization(HttpActionContext actionContext)
        {
            base.OnAuthorization(actionContext);
            var context = Context.User;

            if ((context.IsAuthenticated && context.Name.Equals(_user)))
                return;

            actionContext.Response =
                actionContext.ControllerContext.Request.CreateErrorResponse(HttpStatusCode.Unauthorized,
                    "Unauthorized Access; User is " + Context.User.LocalName);
        }
    } 

Then you need to decorate your method with this attribute:

[AuthorizedUser(@"sitecore\ServicesAPI")]

Your class would look like this:

[ServicesController]    
public class ExampleController : ServicesApiController
{
    [AuthorizedUser(@"sitecore\ServicesAPI")]
    public ActionResult Index()
    {
        return null;
    }
}

Some config changes are also needed to make this working. Example codes and config files can be found in really nice post by Boris Brodsky: http://borisbrodsky.com/sitecore/sitecore-webapi-servicesapicontroller-and-jwt-token-security/

4
  • Thanks @Peter. I had seen that post and thought about taking that approach. I guess what I was looking for is if some kind of AuthorizedUser filter already exists or if there is a way of tapping into what the ItemService does with the login endpoint. If I need to do this all myself thats fine but I was trying to avoid adding any extra code and config if not needed. Thanks for the example anyway. Apr 4, 2018 at 12:25
  • I was also looking into Sitecore.Services.Client and Sitecore.Service.Core assemblies but couldn't find anything useful for you. That's why I wrote this answer as it seems there is no other option expect of this one. Apr 4, 2018 at 13:37
  • What is the purpose of calling base.OnAuthorization(actionContext); Is this necessary and is the location where it's called important?
    – TxRegex
    Sep 13, 2022 at 18:56
  • @TxRegex It's a good practive to call base.method when you override method. Usually it's virtual method and has some basic implementation. With override method you are adding something on top. That's why it's better to call it as first. So position matters sometimes. Here it matters as it probably does something with actionContext and you are working with it within override method. Sep 13, 2022 at 19:06
3

Since you say you were thinking of requiring the use of the auth/login endpoint before requests can be made to your custom controller, what you can do is add the Authorize filter as an attribute to the controller or specific actions like this:

[Authorize]
public class ExampleController : ServicesApiController
{
    public ActionResult Index()
    {
        return null;
    }
}

That will only exclude access to anonymous users, in case you want to be more specific you can use something like this:

  • [Authorize(Users="Alice,Bob")]
  • [Authorize(Roles="Administrators")]

And then you can authenticate through the sitecore/api/ssc/auth/login endpoint.

1
  • Thanks Richard. I'll take a look at this when I come back to this next week. Aug 8, 2018 at 16:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.