Identity Server 4从外部提供商注册用户 [英] Identity Server 4 Register Users from External Providers

查看:176
本文介绍了Identity Server 4从外部提供商注册用户的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试从外部登录返回的声明中存储新用户的数据.

I'm trying to store new users data from the claims return from an external login.

让我们说我有一个模型

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

以及将用户添加到数据库的方法:

and a method to add a user to the Database:

_userService.Add(new User()); 

这是他们永恒的登录回叫的标准IdentityServer实现.

This is the standard IdentityServer implementation for their eternal login call back.

[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登录,我不能使用其电子邮件地址作为唯一ID,因为他们可能已经使用其他提供商的电子邮件进行了注册?

My question is how can I retrieve a unique Identifier for each user that logs in? Say a user logs in via google, I Cannot use their email address as a unique id because they potentially could already have registered using that email from another provider?

推荐答案

您可能需要构造某种形式的标识符,该标识符来自外部提供商发出的令牌.在OpenID Connect中,假定主题声明对于提供者在本地是唯一的.构造全局唯一标识符的一种方法是使用令牌的发行者(iss)声明和主题(sub)声明某种组合密钥(或构造的密钥),通常可以保证此标识符成为全球唯一.

You might need to construct some form of identifier that comes from the token issued from the external provider. In OpenID Connect the subject claim is assumed to be locally unique to the provider. One way to construct a globally unique identifier is to make some sort of composite key (or constructed key) that uses both the issuer (iss) claim and the subject (sub) claim of the token, this identifier is generally guaranteed to be globally unique.

这篇关于Identity Server 4从外部提供商注册用户的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆