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

查看:64
本文介绍了通过外部(自定义)服务登录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.

我的问题是我无法使用数据库.我必须使用一项服务(将内部DDL连接到我们的系统的WCF服务),该服务只能登录(我给它提供用户名和密码),登录后我可以获取许可列表.

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?

感谢您的每条建议.

我已经检查了一些文章

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

Microsoft - custom storage providers
Core indentity without entity framework
Sikorsky blog - custom user manager

推荐答案

实际上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));
}

要创建访问令牌,请执行以下操作:

To create an access token:

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天全站免登陆