tschuege
tschuege

Reputation: 761

Kentor Auth Services - Additional Claim

I'm evaluating the Kentor auth services (the OWIN version of it) to authenticate users using SAML. Now I would like to pass an additional claim to the service. Together with the samples there I was able to send the request to the service and debug it.

I made a custom claimsAuthenticationManager and there I can see the additional claim arriving at the auth service. But later on (in the Kendor examples there is a the view home/index listing all the claims) this claim is not available anymore. Does anyone have an idea what i'm doing wrong?

Thanks a lot!

Upvotes: 4

Views: 2449

Answers (1)

Anders Abel
Anders Abel

Reputation: 69260

When using AuthServices (or any external login) together with ASP.NET Identity, the incoming claims are only used for looking up the ASP.NET Identity user in the database. Then incoming user is then discarded completely and the user from ASP.NET Identity is loaded and used

In the default MVC5 template, the switch from the external identity to the ASP.NET Identity is done in AccountController.ExternalLoginCallback(). To keep the incoming information you have to adjust this method. There are two options.

1. Update stored user in ExternalLoginCallback()

// Sign in the user with this external login provider if the user already has a login
var user = await UserManager.FindAsync(loginInfo.Login);
if (user != null)
{
  // Update user with info from external identity and save.
  user.GivenName = loginInfo.ExternalIdentity.FindFirst(ClaimTypes.GivenName).Value;
  await UserManager.UpdateAsync(user);

  await SignInAsync(user, isPersistent: false);
  return RedirectToLocal(returnUrl);
}

2. Use the incoming claims for current session only.

Copy the contents of SignInAsync() to your ExternalLoginCallback() method. Extract the call to user.GenerateUserIdentityAsync()to a separate line and. Add claims before callingSignInAsync()`

// Sign in the user with this external login provider if the user already has a login
var user = await UserManager.FindAsync(loginInfo.Login);
if (user != null)
{
  AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie);
  var identity = await user.GenerateUserIdentityAsync(UserManager);
  identity.AddClaim(loginInfo.ExternalIdentity.FindFirst(ClaimTypes.GivenName));
  AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = isPersistent },
    identity);

  return RedirectToLocal(returnUrl);
}

Suggestion

It is also possible to use external login without ASP.NET Identity. If you're only using identities from the Idp and no other login method, that is probably easier to work with.

Upvotes: 5

Related Questions