Identity Server 4 Регистрация пользователей от внешних поставщиков

Я пытаюсь сохранить данные о новых пользователях из заявок, возвращаемых из внешнего входа.

скажем так, у меня есть модель

public class User
{
    Guid UniqueIdentifier;
    string Username;
    string Firstname;
    string LastName;
    string Email;
    Date DateOfBirth;
}

и способ добавления пользователя в базу данных:

_userService.Add(new User()); 

Это стандартная реализация IdentityServer для их вечного обратного вызова при входе в систему.

[HttpGet]
public async Task<IActionResult> ExternalLoginCallback(string returnUrl)
{
    // read external identity from the temporary cookie
    var info = await HttpContext.Authentication.GetAuthenticateInfoAsync(IdentityServerConstants.ExternalCookieAuthenticationScheme);
    var tempUser = info?.Principal;
    if (tempUser == null)
    {
        throw new Exception("External authentication error");
    }

    // retrieve claims of the external user
    var claims = tempUser.Claims.ToList();

    // try to determine the unique id of the external user - the most common claim type for that are the sub claim and the NameIdentifier
    // depending on the external provider, some other claim type might be used
    var userIdClaim = claims.FirstOrDefault(x => x.Type == JwtClaimTypes.Subject);
    if (userIdClaim == null)
    {
        userIdClaim = claims.FirstOrDefault(x => x.Type == ClaimTypes.NameIdentifier);
    }
    if (userIdClaim == null)
    {
       throw new Exception("Unknown userid");
    }

    // remove the user id claim from the claims collection and move to the userId property
    // also set the name of the external authentication provider
    claims.Remove(userIdClaim);
    var provider = info.Properties.Items["scheme"];
    var userId = userIdClaim.Value;

    // check if the external user is already provisioned
    var user = await _userManager.FindByLoginAsync(provider, userId);
    if (user == null)
    {
        user = new IdentityUser { UserName = Guid.NewGuid().ToString() 
    };

    await _userManager.CreateAsync(user);

    await _userManager.AddLoginAsync(user, new UserLoginInfo(provider, userId, provider));
    }

    var additionalClaims = new List<Claim>();

    // if the external system sent a session id claim, copy it over
    var sid = claims.FirstOrDefault(x => x.Type == JwtClaimTypes.SessionId);
    if (sid != null)
    {
        additionalClaims.Add(new Claim(JwtClaimTypes.SessionId, sid.Value));
    }

    // issue authentication cookie for user
    await HttpContext.Authentication.SignInAsync(user.Id, user.UserName, provider, additionalClaims.ToArray());

    // delete temporary cookie used during external authentication
    await HttpContext.Authentication.SignOutAsync(IdentityServerConstants.ExternalCookieAuthenticationScheme);

    // validate return URL and redirect back to authorization endpoint
    if (_interaction.IsValidReturnUrl(returnUrl))
    {
        return Redirect(returnUrl);
    }

    return Redirect("~/");
}

У меня вопрос: как получить уникальный идентификатор для каждого пользователя, который входит в систему? Скажем, пользователь входит в систему через Google, я не могу использовать его адрес электронной почты в качестве уникального идентификатора, потому что он потенциально мог уже зарегистрироваться, используя этот адрес электронной почты от другого провайдера?


person johnny 5    schedule 12.03.2017    source источник


Ответы (1)


Возможно, вам потребуется создать некоторую форму идентификатора, который поступает из токена, выданного внешним поставщиком. В OpenID Connect предполагается, что предметное утверждение является локально уникальным для поставщика. Один из способов создания глобального уникального идентификатора - создать своего рода составной ключ (или сконструированный ключ), который использует как утверждение эмитента (iss), так и утверждение субъекта (sub) токена, этот идентификатор обычно гарантированно будет глобально уникальным. .

person Lutando    schedule 12.03.2017
comment
Спасибо, вы можете привести пример? - person johnny 5; 12.03.2017