Service authorization depending on runtime environment?

I currently have several runtime environtments such as development, test, prod, etc. For testing and development in the datacenter deployment I need to openup some of the REST APIs for powershell CLI.

Is it possible to define authentication based on an #ifdef pragma? I am looking for something like

[Authenticate]
#if DEV_DATACENTER
[RequiresAnyRole("Administrator", "SysOp", "Dev")]
#else
[RequiresAnyRole("Administrator", "SysOp")]
#endif
public object Put(MyRequest someRequest)
{

}

Or any other smart way to define service authorisation depending on a runtime environment. I set runtime environments through commandline / docker file / docker-compose or kubernetes .yaml files. Any sugestions or best practice for such things?

Just another thought:
Would a RequestFilter be a suitable solution? Something like

[RequiresAnyRole("Administrator",  "SysOp", "SomeDevRole")]

and then in the filter I should have the possibility to first let servicestack process the standard RequiresRole attribute and than plugin an additonal check like so (kind of pseude C# code)

this.GlobalRequestFilters.Add((req, res, requestDto) => {
    //Standard role check... How??
    var runtime = HostContext.TryResolve(runtime);
    if (runtime != dev_datacenter && Role == "SomeDevRole"")
    {
        res.Return...... //is there a Not allowed response??
    }
});

Yes you can use build symbols to change the implementation and behaviour, do you know how they work and how to define build symbols?

Use req.GetSession().HasRole() to check for roles.

But I don’t understand why you’re not using the most obvious solution of having different roles for users in different environments instead of changing the code in different environments?

But I don’t understand why you’re not using the most obvious solution of
having different roles for users in different environments instead of
changing the code in different environments?

The software is the same in all environments and some of the users and their roles are created by business logic, e.g. when you call a specific REST API it creates a tenant and some initial users for that tenant. The same is true for some ‘technical’ users who get API keys to interface with my services. For testing their interfaces it is a lot handier to use some predefined powershell or bash scripts instead of clicking around in a GUI (thats for end users, not for devs or sysops).

These functions should only be available in DEV or TEST runtime environment, but not in Demo or Production.

do you know how they work and how to define build symbols?

Well more or less, I used them million times in C/C++ but I saw that they have some limitations in C# vs C/C++. In fact they are pre-processor statements and I don’t like them too much since it is cluttering up the code. While this is more or less “normal” in C it seems to be uncommon in C#. But because it makes code unreadable I prefer a RequestFilter and try this one out.

One more question: Can I define a custom response in such a filter. In your documentation you have a sample where you return

if (sessionId == null)
{
    res.ReturnAuthRequired();
}

What exactly is ReturnAuthRequired() and can I define something like NotAllowedInProductionEnvironment() ?

You can just search the repository for ReturnAuthRequired() which is just an extension method:

If you want to short-circuit the request to deny access, returning Forbidden StatusCode would be more appropriate:

GlobalRequestFIlters.Add((req,res,dto) => {
    //...
    res.StatusCode = (int)HttpStatusCode.Forbidden;
    res.StatusDescription = "Thou shall not pass";
    res.EndRequest();
});

See the docs on Request/Response Filters for more examples.

Great, thanks a lot Demis. Need to think about the design a little bit first, to see which is the best solution for my requirements…