Lathezar Mitev
Lathezar Mitev

Reputation: 23

Adding a header in ActionFilterAttribute

I'm trying to assign a token to my header in the request and when the action has finished to save a new token. Problem is that it assigns it to the HttpContext.Request.Headers and not to the client that is calling the API.

ActionFilter

public class TokenFilter: ActionFilterAttribute {
    private static string _token {
        get;
        set;
    }

    public override void OnActionExecuting(ActionExecutingContext filterContext) {
        base.OnActionExecuting(filterContext);
        if (_token != null) {
            filterContext.HttpContext.Request.Headers.Add("AuthToken", "Token " + _token);
        }
    }

    public override void OnActionExecuted(ActionExecutedContext filterContext) {
        base.OnActionExecuted(filterContext);

        _token = filterContext.HttpContext.Request.Headers["AuthToken"];
        _token = _token.Substring(_token.IndexOf(" "));
        _token = _token.Remove(0, 1);

        if (Client.DefaultRequestHeaders.Contains("AuthToken"))
    }
}

Controller Action

[HttpPost]
[TokenFilter]
public async Task < IActionResult > LogIn(User user) {
    try {

        client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(
        Encoding.UTF8.GetBytes(user.Username + ":" + user.Password)));

        HttpResponseMessage clientTask = await client.GetAsync("https://localhost:44324/api/Auth/LogIn");

        if (clientTask.IsSuccessStatusCode) {
            string txtBlock = await clientTask.Content.ReadAsStringAsync();

            var tokenObject = JsonConvert.DeserializeObject < SessionAPI > (txtBlock);

            client.DefaultRequestHeaders.Authorization = null;

            client.DefaultRequestHeaders.Add("AuthToken", "Token " + tokenObject.Token);

            return RedirectToAction("Index", "Home");
        }
        else return View("LogInIndex", user);
    }
    catch(Exception e) {
        throw new Exception("An Error has occured" + e);
    }
}

The main idea is to have a token that after LogIn is to be assigned to every request that is sent to the API untill Log Out. I know that i can use cookies but part of the assignment is not to use them. Currently i have the Token just being a static string for testing, but that eventually has to be moved somewhere dynamicly for every User.

EDIT This is an example method that can be called after a successful Log In

[HttpGet]
        [TokenFilter]
        public async Task<IActionResult> ListAll()
        {
            try
            {
                //client.DefaultRequestHeaders.Add("AuthToken", "Token " + HttpContext.Request.RouteValues["token"]);

                HttpResponseMessage clientTask = await client.GetAsync("https://localhost:44324/api/User/ListAll");

                if (clientTask.IsSuccessStatusCode)
                {

                    string txtBlock = await clientTask.Content.ReadAsStringAsync();

                    List<User> users = JsonConvert.DeserializeObject<List<User>>(txtBlock);

                    client.DefaultRequestHeaders.Authorization = null;


                    return View("ListAll", users);
                }
                else
                    return RedirectToAction("Index", "Home");
            }
            catch (Exception e)
            {
                throw new Exception("An Error has occured" + e);
            }
        }

Upvotes: 2

Views: 3221

Answers (1)

Imad
Imad

Reputation: 7490

You don't have to override OnActionExecuting

You can do this as follow

public class TokenFilter: ActionFilterAttribute
{
    public override void OnActionExecuted(HttpActionExecutedContext filterContext)
    {
       if (_token != null) 
       {
           filterContext.Response.Headers.Add("AuthToken", "Token " + _token);
       }
    }
}

Upvotes: 1

Related Questions