ASP 核心通过外部(自定义)服务登录 [英] ASP core login through external (custom) service

查看:14
本文介绍了ASP 核心通过外部(自定义)服务登录的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找如何实施身份验证和授权的正确方法.如果我理解得很好 - 这应该通过身份"来实现.- 它提供了我需要的这两种东西.

I am looking for proper way how to implement authentification and authorization. If I understand it well - this should be realized through "Identity" - it's offering both of these things I need.

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

My problem is that i can't use a database. I have to use a service (WCF service where our internal DDLs are connected to our system) which is able only Login (I give it user name and password) and after login i can get list of permissons.

我已经看过如何自定义 UserStore、RoleStore、UserManager 和 SignInManager 的文章了.. 但我仍然很困惑,我不知道该怎么做.

I already saw articles how to have custom UserStore, RoleStore, UserManager and SignInManager.. but I am still confused and I don't know how to do it.

这甚至可以通过身份模型实现吗?如果不是我应该怎么做?

Is this even posible through Identity model? If not how I should do it please?

感谢您的每一个建议.

有些文章我已经查过了:

There are some articles which I already checked:

Microsoft - 自定义存储提供商
没有实体框架的核心身份
西科斯基博客 - 自定义用户管理器

推荐答案

实际上 WCF 服务就是您的身份验证服务.无需执行两次.对该服务的调用会验证凭据并返回访问令牌中应包含的所有内容.

In fact the WCF service is your authentication service. No need to implement this twice. A call to the service verifies the credentials and returns everything that should be in the access token.

基本上,您所要做的就是使用来自 WCF 服务的信息生成访问令牌.并将您的应用配置为使用创建的访问令牌.

Basically all you have to do is generate an access token using the information from the WCF service. And configure your app to use the created access token.

流程可以是这样:首先调用 WCF 服务以验证登录并检索信息.

The flow can be like this: first make a call to the WCF service in order to verify the login and retrieve the information.

public async Task<IActionResult> 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<Claim>
        {
            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 在哪里:

Where AccessToken is:

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

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

And add authentication in your startup:

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, _audience and _secret are from some 'external source'. Meaning that all three are fixed string values, but the source (where the value is set) is variable.

对于 _issuer,您通常使用发布令牌的服务器的 url.喜欢http://www.mywebsite.com/myapp_audience 是用于接受令牌的应用程序.在这种情况下,_issuer 和 _audience 是相同的,因此您可以使用相同的值.

For _issuer you usually use the url of the server that issues the token. Like http://www.mywebsite.com/myapp The _audience is the application that is meant to accept the token. In this case _issuer and _audience are the same, so you can use the same value.

_secret 是秘密,可以是任何字符串,例如 'my_super_secret'.这是你想要保密的事情.因此,您无需对其进行硬编码,而是从安全位置获取它.

_secret is, well secret and can be any string, like 'my_super_secret'. This is something you want to stay secret. So you don't hardcode it, but get it from a safe location instead.

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

I've updated above code in a way so you can test it. Please note that secret should not be hardcoded.

这篇关于ASP 核心通过外部(自定义)服务登录的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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