CredentialsAuthProvider add custom field to request

Hi is it possible to add custom parameter to CredentialsAuthProvider authenticate request?

public override object Authenticate(IServiceBase authService, IAuthSession session, Authenticate request)

has built in Authenticate object,

The built-in Authenticate Request DTO is pre-defined so it can’t be modified, you can add additional metadata in the Authenticate.Meta dictionary otherwise you can still add it to the QueryString/FormData of the HTTP Request but it wont be populated on the Authenticate but you can still access it from:

authService.Request.QueryString
authService.Request.FormData

Is there a way to write my own version of credentialsauthprovider where I can implement my custom DTO?

No AuthProviders goes through the AuthenticateService which is called with the Authenticate Request DTO.

The easiest solution is to add an extension method to Authenticate Request DTO which will give you a Typed API, e.g:

public static Authenticate CustomProperty(this Authenticate request, string value)
{
    request.Meta = new Dictionary<string,string> {
        {"CustomProperty", value}
    };
    return this.
}

That you could be called like:

client.Post(new Authenticate
{
    provider = "credentials",
    UserName = userName,
    Password = password,
}.CustomProperty("foo"));

Also a builder pattern would work pretty good here as well, e.g:

public class MyAutenticate
{
    public string UserName { get; set; }
    public string Password { get; set; }
    public string CustomProperty { get; set; }

    public Authenticate Build() => 
        new Authenticate {
            Provider = "credentials",
            UserName = UserName,
            Password = Password,
            Meta = new Dictionary<string,string> {
                { "CustomProperty", requestDto.CustomProperty }
            }
        };
}

Which you can call with:

client.Post(new MyAuthenticate
{
    UserName = userName,
    Password = password,
    CustomProperty = "foo",
}.Build());

Other solutions would require a custom mock Request DTO which simulates a Authenticate request by serializing to the same wire-format that Authenticate expects, e.g:

[Route("/auth/{provider}")]
public class MyAutenticate : IPost, IReturn<AuthenticateResponse>, IMeta
{
    public MyAutenticate()
    {
        this.Provider = "credentials";
        this.Meta = new Dictionary<string,string>();
    }
    public string Provider { get; set; }
    public string UserName { get; set; }
    public string Password { get; set; }
    public string CustomProperty 
    {
        set { Meta["CustomProperty"] = value; }
    }
    public Dictionary<string,string> Meta { get; set; }
}

Another option may be to use a [Request Converter][1] to convert your Custom Request DTO into the Authenticate DTO that the AuthenticateService expects, e.g:

public class MyAuthenticate
{
    public string UserName { get; set; }
    public string Password { get; set; }
    public string CustomProperty { get; set; }
}
```

Then add a converter to convert it to `Authenticate` DTO, e.g:

```csharp
appHost.RequestConverters.Add((req, requestDto) => {
    var myAuth = requestDto as MyAuthenticate;
    if (myAuth == null) return null;
    return new Authenticate {
        Provider = "credentials",
        UserName = requestDto.UserName,
        Password = requestDto.Password,
        Meta = new Dictionary<string,string> {
            { "CustomProperty", requestDto.CustomProperty }
        }
    };
});
```

There's the different solutions I can think of atm, but if you wanted to avoid `Authenticate` completely you'd need to implement your own AuthFeature to use instead of ServiceStack's.





  [1]: http://docs.servicestack.net/customize-http-responses#request-and-response-converters