ASP核心通过外部(自定义)服务登录

我正在寻找如何实现身份validation和授权的正确方法。 如果我理解得很好 – 这应该通过“身份”来实现 – 它提供了我需要的这些东西。

我的问题是我不能使用数据库。 我必须使用一个服务(我们的内部DDL连接到我们的系统的WCF服务),它只能登录(我给它用户名和密码),登录后我可以获得许可列表。

我已经看过文章如何有自定义UserStore,RoleStore,UserManager和SignInManager ..但我仍然感到困惑,我不知道该怎么做。

这通过身份模型是否可行? 如果不是我应该怎么做呢?

谢谢你的建议。

我已经检查了一些文章:

Microsoft – 自定义存储提供程序
没有entity framework的核心身份
西科斯基博客 – 自定义用户管理器

实际上,WCF服务是您的身份validation服务。 无需实施两次。 对服务的调用将validation凭据并返回访问令牌中应包含的所有内容。

基本上,您所要做的就是使用WCF服务中的信息生成访问令牌。 并配置您的应用程序以使用创建的访问令牌。

流程可以是这样的:首先调用WCF服务以validation登录并检索信息。

public async Task LoginAsync([FromBody]UserLogin login) { var loginInfo = _wcf.LoginUser(login); if (loginInfo == null) return Unauthorized(); return Ok(CreateAccessToken(loginInfo)); } 

要创建访问令牌:

 public class TokenHelper { public const string Issuer = "http://www.mywebsite.com/myapp"; public const string Audience = "http://www.mywebsite.com/myapp"; // This should not be hardcoded! public const string Secret = "My_super_secret"; public AccessToken CreateAccessToken(LoginInfo loginInfo) { // Set expiration time of 5 minutes. DateTime expires = DateTime.UtcNow.AddMinutes(5); var claims = new List { new Claim(JwtRegisteredClaimNames.Sub, loginInfo.UserId), new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()) }; // Add custom claims, rolepermissions if (loginInfo.Permissions != null && loginInfo.Permissions.Any()) loginInfo.Permissions.foreach(p => claims.Add(new Claim("Permission", p))); if (loginInfo.IsUser) claims.Add(new Claim(ClaimTypes.Role, "User")); if (loginInfo.IsAdmin) claims.Add(new Claim(ClaimTypes.Role, "Admin")); var token = new JwtSecurityToken( issuer: Issuer, audience: Audience, claims: claims, expires: expires, signingCredentials: new SigningCredentials( new SymmetricSecurityKey(Encoding.ASCII.GetBytes(Secret)), SecurityAlgorithms.HmacSha256 ) ); return new AccessToken { ServerTime = DateTime.UtcNow.ToString("yyyyMMddTHH:mm:ssZ"), Expires = expires.ToString("yyyyMMddTHH:mm:ssZ"), Bearer = new JwtSecurityTokenHandler().WriteToken(token) }; } } 

AccessToken的位置是:

 public class AccessToken { public string ServerTime { get; set; } public string Expires { get; set; } public string Bearer { get; set; } } 

并在您的启动中添加身份validation:

 services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(options => { options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidateAudience = true, ValidateLifetime = true, ValidateIssuerSigningKey = true, RequireExpirationTime = true, RequireSignedTokens = true, ValidIssuer = TokenHelper.Issuer, ValidAudience = TokenHelper.Audience, IssuerSigningKey = new SymmetricSecurityKey( Encoding.ASCII.GetBytes( TokenHelper.Secret)) }; } ); 

– 更新 –

_issuer,_audience和_secret来自某些“外部来源”。 这意味着所有三个都是固定的字符串值,但源(设置值)是可变的。

对于_issuer,您通常使用颁发令牌的服务器的URL。 与http://www.mywebsite.com/myapp一样_audience是用于接受令牌的应用程序。 在这种情况下,_issuer和_audience是相同的,因此您可以使用相同的值。

_secret是,很好的秘密,可以是任何字符串,如'my_super_secret' 。 这是你想要保密的东西。 所以你不要硬编码,而是从安全的位置获取它。

我已经以某种方式更新了上面的代码,以便您可以对其进行测试。 请注意,秘密不应该是硬编码的。