0

I am making an MVC/AngularJs SPA with Entity Framework. I am saving a vehicle to my database and trying to also save the current logged in user by UserId as a foreign key, but the result is always null. I am using Identity for authorization and authentication.

VehicleController.cs (everything in comments is what I tried so far, always null, so I guess the problem might be somewhere else):

    [Authorize]
    [Route("")]
    public async Task<IHttpActionResult> PutVehicle(Vehicle vehicle)
    {

    //vehicle.UserId = HttpContext.Current.GetOwinContext().GetUserManager<UserModel>().UserId;
    //vehicle.UserId = User.Identity.GetUserId();
    //vehicle.UserId = Request.GetOwinContext().Authentication.User.Identity.GetUserId();
    //vehicle.UserId = HttpContext.Current.GetOwinContext().Authentication.User.Identity.GetUserId();
    //vehicle.UserId = RequestContext.Principal.Identity.GetUserId();
    //vehicle.UserId = HttpContext.Current.User.Identity.GetUserId();

    vehicle.Discontinued = false;
    this.Validate(vehicle);
    if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }

    _db.Vehicles.Add(vehicle);
    await _db.SaveChangesAsync();
    return Ok();
}

The Vehicle Model:

public class Vehicle
    {
        [Key]
        public int VehicleId { get; set; }
        public string UserId { get; set; }
        public string LicenseNumber { get; set; }
        public string Company { get; set; }
        public bool Discontinued { get; set; }

        [JsonIgnore]
        public List<Trip> Trips { get; set; }
        [JsonIgnore]
        public UserModel User { get; set; }
    }

VehicleController.js:

vm.addVehicle = function () {
                vehicleService.addVehicle(vm.newVehicle).then(function() {
                    vm.savedSuccessfully = "Your vehicle was added successfully!";
                    vm.getAllVehicles();
                });
            }

VehicleService.js:

var _addVehicle = function(vehicle) {
                    var deferred = $q.defer();
                    $http.put(serviceBase + 'api/vehicle',
                            vehicle,
                            { headers: { 'Authorization': 'Bearer' + authService.authentication.token } })
                        .success(function(response) {
                            deferred.resolve(response);
                        }).error(function (error, status) {
                            console.log(status);
                            console.log(error);
                            deferred.reject(error);
                        });
                    return deferred.promise;
                };

I really don't know what I'm looking for anymore.

Edit: Updating with some more stuff that might be relevant to the problem I'm having.

authService.js:

var _login = function(loginData) {

                var data = "grant_type=password&username=" + loginData.userName + "&password=" + loginData.password;

                var deferred = $q.defer();

                $http.post(serviceBase + 'token',
                    data,
                    { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }).success(function(response) {


                    localStorageService.set('authorizationData',
                        { token: response.access_token, userName: loginData.userName });

                    _authentication.isAuth = true;
                    _authentication.userName = loginData.userName;

                    deferred.resolve(response);

                }).error(function(err, status) {
                    _logOut();
                    deferred.reject(err);
                });

                return deferred.promise;

            };

authInterceptorService.js

var _request = function(config) {

                config.headers = config.headers || {};

                var authData = localStorageService.get('authorizationData');
                if (authData) {
                    config.headers.Authorization = 'Bearer ' + authData.token;
                }
                return config;
            }

SimpleAuthorizationServerProvider.cs

public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
        {

            context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });

            using (AuthRepository _repo = new AuthRepository())
            {
                IdentityUser user = await _repo.FindUser(context.UserName, context.Password);

                if (user == null)
                {
                    context.SetError("invalid_grant", "The user name or password is incorrect.");
                    return;
                }
            }

            ClaimsIdentity identity = new ClaimsIdentity(OAuthDefaults.AuthenticationType);
            identity.AddClaim(new Claim("sub", context.UserName));
            identity.AddClaim(new Claim("role", "user"));

            context.Validated(identity);

        }

AuthRepository.cs

public async Task<IdentityUser> FindUser(string userName, string password)
        {
            IdentityUser user = await _userManager.FindAsync(userName, password);

            return user;
        }
Koalemos
  • 41
  • 10
  • All you need is `User.Identity.GetUserId()`. There's no way that's null unless the user isn't logged in, but based on your action, they wouldn't be able to access it unless they are. As a result, are you sure `User.Identity.GetUserId()` is actually null? It's entirely possible `vehicle.UserId` is simply being set null later by some other bit of code somewhere. – Chris Pratt May 11 '17 at 17:50
  • Yeah, it is always null. And it's not being set to null later cause I checked by putting a breakpoint on vehicle.UserId = User.Identity.GetUserId();. Everything else is correct, Company, Discontinued, LicenseNumber all got values. – Koalemos May 11 '17 at 18:11
  • If that's null and the user is in fact logged in, then there's something seriously misconfigured with Identity. – Chris Pratt May 11 '17 at 18:14
  • Yeah, tell me about it... – Koalemos May 11 '17 at 18:21
  • I found this that might be of help to you: http://stackoverflow.com/a/26453782/654031. Supposedly, manually setting a claim with the user id, will get `User.Identity.GetUserId()` to actually return something not null. From what I can gather, under a claims-based auth scenario, it will be null otherwise. – Chris Pratt May 11 '17 at 18:27
  • Are you using Identity 2.0? or still on 1.0? This seems like a bug, and one that would have been solved by 2.0. – Chris Pratt May 11 '17 at 18:28
  • I'm using Identity 2.0. I don't think it's a bug, it's probably just bad coding on my part somewhere – Koalemos May 11 '17 at 18:59
  • What grant_type are you using when retrieving a token? –  May 11 '17 at 20:40
  • I added to original question everything that might be of interest. – Koalemos May 12 '17 at 07:34
  • Was that enough information for you to help me find the cause of my problems? Is it this that you mean; "grant_type=password&username=" + loginData.userName + "&password=" + loginData.password;? – Koalemos May 14 '17 at 18:40

0 Answers0