Вход пользователя через удаленные сервисы и про TokenAuthController - PullRequest
0 голосов
/ 25 марта 2019

Мне нужно войти в систему, используя только удаленные сервисы.Я думаю, используя TokenAuthController в приложении Web.Core

Я действительно не могу понять, почему приведенный ниже фрагмент не работает.Я добавил новый метод под названием Login в TokenAuthController.

using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Abp.Authorization;
using Abp.Authorization.Users;
using Abp.MultiTenancy;
using Abp.Runtime.Security;
using Abp.UI;
using Abp.Web.Models;
using Microsoft.AspNetCore.Authorization;
using TSE.DergiAbone.Authentication.External;
using TSE.DergiAbone.Authentication.JwtBearer;
using TSE.DergiAbone.Authorization;
using TSE.DergiAbone.Authorization.Users;
using TSE.DergiAbone.Identity;
using TSE.DergiAbone.Models.TokenAuth;
using TSE.DergiAbone.MultiTenancy;

namespace TSE.DergiAbone.Controllers
{
    [Route("api/[controller]/[action]")]
    public class TokenAuthController : DergiAboneControllerBase
    {
        private readonly LogInManager _logInManager;
        private readonly SignInManager _signInManager;

        private readonly ITenantCache _tenantCache;
        private readonly AbpLoginResultTypeHelper _abpLoginResultTypeHelper;
        private readonly TokenAuthConfiguration _configuration;
        private readonly IExternalAuthConfiguration _externalAuthConfiguration;
        private readonly IExternalAuthManager _externalAuthManager;
        private readonly UserRegistrationManager _userRegistrationManager;

        public TokenAuthController(
            LogInManager logInManager,
            SignInManager signInManager,
            ITenantCache tenantCache,
            AbpLoginResultTypeHelper abpLoginResultTypeHelper,
            TokenAuthConfiguration configuration,
            IExternalAuthConfiguration externalAuthConfiguration,
            IExternalAuthManager externalAuthManager,
            UserRegistrationManager userRegistrationManager)
        {
            _logInManager = logInManager;
            _tenantCache = tenantCache;
            _abpLoginResultTypeHelper = abpLoginResultTypeHelper;
            _configuration = configuration;
            _externalAuthConfiguration = externalAuthConfiguration;
            _externalAuthManager = externalAuthManager;
            _userRegistrationManager = userRegistrationManager;
            _signInManager = signInManager;
        }
        ***[HttpPost]
        public virtual async Task<JsonResult> Login(string UserName, string password,bool IsPersistent )
        {

            var loginResult = await GetLoginResultAsync(UserName, password, GetTenancyNameOrNull());

            //var result = await _signInManager.SignInAsync(loginResult.Identity, IsPersistent);
            var result = await _signInManager.PasswordSignInAsync(UserName, password, true, false);
            if (result.Succeeded)
           {
              long bak= User.Identity.GetUserId().Value;
                string res = "User signed in";
           }
            await UnitOfWorkManager.Current.SaveChangesAsync();
            bool chk = User.Identity.IsAuthenticated;
            return Json(new Abp.Web.Models.AjaxResponse { TargetUrl = "" });
        }***







        [HttpPost]
        public async Task<AuthenticateResultModel> Authenticate([FromBody] AuthenticateModel model)
        {
            var loginResult = await GetLoginResultAsync(
                model.UserNameOrEmailAddress,
                model.Password,
                GetTenancyNameOrNull()
            );




            //var chk = _logInManager.LoginAsync("jimycarbonare@gmail.com", "123qwe", "TSEDergi").Result;
            //var chk2 = _logInManager.Login("jimycarbonare@gmail.com", "123qwe", "TSEDergi");

            //var name = User.Identity.Name;
            //bool bak0 = User.IsInRole("admin");

            //var accessToken = CreateAccessToken(CreateJwtClaims(loginResult.Identity));
            //var loginResult = await GetLoginResultAsync("jimycarbonare@gmail.com", "123qwe", "TSEDergi");

            //await _signInManager.SignInAsync(loginResult.Identity, model.RememberClient);//_logInManager.LoginAsync("jimycarbonare@gmail.com", "123qwe", "TSEDergi").Result;

            //var name = User.Identity.Name;
            //bool bak0 = User.IsInRole("admin");





            var accessToken = CreateAccessToken(CreateJwtClaims(loginResult.Identity));
            return new AuthenticateResultModel
            {
                AccessToken = accessToken,
                EncryptedAccessToken = GetEncrpyedAccessToken(accessToken),
                ExpireInSeconds = (int)_configuration.Expiration.TotalSeconds,
                UserId = loginResult.User.Id
            };
        }

        [HttpGet]
        public List<ExternalLoginProviderInfoModel> GetExternalAuthenticationProviders()
        {
            return ObjectMapper.Map<List<ExternalLoginProviderInfoModel>>(_externalAuthConfiguration.Providers);
        }

        [HttpPost]
        public async Task<ExternalAuthenticateResultModel> ExternalAuthenticate([FromBody] ExternalAuthenticateModel model)
        {
            var externalUser = await GetExternalUserInfo(model);

            var loginResult = await _logInManager.LoginAsync(new UserLoginInfo(model.AuthProvider, model.ProviderKey, model.AuthProvider), GetTenancyNameOrNull());

            switch (loginResult.Result)
            {
                case AbpLoginResultType.Success:
                    {
                        var accessToken = CreateAccessToken(CreateJwtClaims(loginResult.Identity));
                        return new ExternalAuthenticateResultModel
                        {
                            AccessToken = accessToken,
                            EncryptedAccessToken = GetEncrpyedAccessToken(accessToken),
                            ExpireInSeconds = (int)_configuration.Expiration.TotalSeconds
                        };
                    }
                case AbpLoginResultType.UnknownExternalLogin:
                    {
                        var newUser = await RegisterExternalUserAsync(externalUser);
                        if (!newUser.IsActive)
                        {
                            return new ExternalAuthenticateResultModel
                            {
                                WaitingForActivation = true
                            };
                        }

                        // Try to login again with newly registered user!
                        loginResult = await _logInManager.LoginAsync(new UserLoginInfo(model.AuthProvider, model.ProviderKey, model.AuthProvider), GetTenancyNameOrNull());
                        if (loginResult.Result != AbpLoginResultType.Success)
                        {
                            throw _abpLoginResultTypeHelper.CreateExceptionForFailedLoginAttempt(
                                loginResult.Result,
                                model.ProviderKey,
                                GetTenancyNameOrNull()
                            );
                        }

                        return new ExternalAuthenticateResultModel
                        {
                            AccessToken = CreateAccessToken(CreateJwtClaims(loginResult.Identity)),
                            ExpireInSeconds = (int)_configuration.Expiration.TotalSeconds
                        };
                    }
                default:
                    {
                        throw _abpLoginResultTypeHelper.CreateExceptionForFailedLoginAttempt(
                            loginResult.Result,
                            model.ProviderKey,
                            GetTenancyNameOrNull()
                        );
                    }
            }
        }

        private async Task<User> RegisterExternalUserAsync(ExternalAuthUserInfo externalUser)
        {
            var user = await _userRegistrationManager.RegisterAsync(
                externalUser.Name,
                externalUser.Surname,
                externalUser.EmailAddress,
                externalUser.EmailAddress,
                Authorization.Users.User.CreateRandomPassword(),
                true
            );

            user.Logins = new List<UserLogin>
            {
                new UserLogin
                {
                    LoginProvider = externalUser.Provider,
                    ProviderKey = externalUser.ProviderKey,
                    TenantId = user.TenantId
                }
            };

            await CurrentUnitOfWork.SaveChangesAsync();

            return user;
        }

        private async Task<ExternalAuthUserInfo> GetExternalUserInfo(ExternalAuthenticateModel model)
        {
            var userInfo = await _externalAuthManager.GetUserInfo(model.AuthProvider, model.ProviderAccessCode);
            if (userInfo.ProviderKey != model.ProviderKey)
            {
                throw new UserFriendlyException(L("CouldNotValidateExternalUser"));
            }

            return userInfo;
        }

        private string GetTenancyNameOrNull()
        {
            if (!AbpSession.TenantId.HasValue)
            {
                return null;
            }

            return _tenantCache.GetOrNull(AbpSession.TenantId.Value)?.TenancyName;
        }


        [HttpPost]
        public AbpLoginResult<Tenant, User> GetLoginResult2Async(string usernameOrEmailAddress, string password, string tenancyName)
        {
            var loginResult = _logInManager.LoginAsync(usernameOrEmailAddress, password, tenancyName).Result;

            switch (loginResult.Result)
            {
                case AbpLoginResultType.Success:
                    return loginResult;
                default:
                    throw _abpLoginResultTypeHelper.CreateExceptionForFailedLoginAttempt(loginResult.Result, usernameOrEmailAddress, tenancyName);
            }
        }

        private async Task<AbpLoginResult<Tenant, User>> GetLoginResultAsync(string usernameOrEmailAddress, string password, string tenancyName)
        {
            var loginResult = await _logInManager.LoginAsync(usernameOrEmailAddress, password, tenancyName);

            switch (loginResult.Result)
            {
                case AbpLoginResultType.Success:
                    return loginResult;
                default:
                    throw _abpLoginResultTypeHelper.CreateExceptionForFailedLoginAttempt(loginResult.Result, usernameOrEmailAddress, tenancyName);
            }
        }

        private string CreateAccessToken(IEnumerable<Claim> claims, TimeSpan? expiration = null)
        {
            var now = DateTime.UtcNow;

            var jwtSecurityToken = new JwtSecurityToken(
                issuer: _configuration.Issuer,
                audience: _configuration.Audience,
                claims: claims,
                notBefore: now,
                expires: now.Add(expiration ?? _configuration.Expiration),
                signingCredentials: _configuration.SigningCredentials
            );

            return new JwtSecurityTokenHandler().WriteToken(jwtSecurityToken);
        }

        private static List<Claim> CreateJwtClaims(ClaimsIdentity identity)
        {
            var claims = identity.Claims.ToList();
            var nameIdClaim = claims.First(c => c.Type == ClaimTypes.NameIdentifier);

            // Specifically add the jti (random nonce), iat (issued timestamp), and sub (subject/user) claims.
            claims.AddRange(new[]
            {
                new Claim(JwtRegisteredClaimNames.Sub, nameIdClaim.Value),
                new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
                new Claim(JwtRegisteredClaimNames.Iat, DateTimeOffset.Now.ToUnixTimeSeconds().ToString(), ClaimValueTypes.Integer64)
            });

            return claims;
        }

        private string GetEncrpyedAccessToken(string accessToken)
        {
            return SimpleStringCipher.Instance.Encrypt(accessToken, AppConsts.DefaultPassPhrase);
        }
    }
}

Я получаю разумный loginResult.И метод PasswordSignInAsync возвращается с успехом.На этом этапе я пришел к выводу, что вход в систему в порядкеНо после того, как я проверяю User.Identity.Я вижу, что это ноль.То же самое относится и к методу SignInAsync. Все, что я хочу сделать - это войти в систему только с использованием удаленных сервисов.Спасибо всем ..

1 Ответ

1 голос
/ 07 мая 2019

Я решил проблему, как указано ниже:

  1. Измените метод входа httpost в AccountController приложения Web.Mvc, как показано ниже

    [HttpPost]
    [UnitOfWork]
    public virtual async Task<JsonResult> Login(LoginViewModel loginModel, string returnUrl = "", string returnUrlHash = "")
    {
        var claims = GetClaims(loginModel.UsernameOrEmailAddress, loginModel.Password);
    
    
        if (claims == null)//giriş yapılamadı
        {
            return Json(new AjaxResponse { TargetUrl = "" });
        }
        else
        {
            var identity = new ClaimsIdentity(CookieAuthenticationDefaults.AuthenticationScheme, ClaimTypes.Name,
                ClaimTypes.Role);
            foreach (var claim in claims)
            {
                identity.AddClaim(new Claim(claim.type, claim.value));
            }
    
            //AbpSession.UserId=18;
            //// Authenticate using the identity
            //var principal = new ClaimsPrincipal(identity);
            //await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, principal, new AuthenticationProperties { IsPersistent = true });
            //bool chk = User.Identity.IsAuthenticated;
            ////bool bak = User.Identity.IsAuthenticated;
            //bool bak2 = User.IsInRole("Admin");
            //return RedirectToAction("Index", "Home");
            await _signInManager.SignInAsync(identity, loginModel.RememberMe);
            await UnitOfWorkManager.Current.SaveChangesAsync();
            bool bak = User.Identity.IsAuthenticated;
            var bakl = AbpSession.UserId;
        }
    
    
        returnUrl = NormalizeReturnUrl(returnUrl);
        if (!string.IsNullOrWhiteSpace(returnUrlHash))
        {
            returnUrl = returnUrl + returnUrlHash;
        }
    
    
    
        return Json(new AjaxResponse { TargetUrl = returnUrl });
    }
    
  2. Создание метода GetClaims в AccountController приложения Web.Mvc

        protected List<ClaimRootObject> GetClaims(string UserName, string Password)
    {
    
        using (var client = new HttpClient())
        {
            string reqString = "http://localhost:21021/api/" + "TokenAuth/GetClaims/GetClaims?UserName=" + UserName + "&password=" + Password + "&TenantName=Default";
            //string reqString = "http://localhost:81/api/TokenAuth/GetClaims/GetClaims?UserName=admin&password=123qwe&TenantName=TSEDergi";
            HttpResponseMessage response = client.GetAsync(reqString).Result; // Blocking call!  
            if (response.IsSuccessStatusCode)
            {
                // Get the response
                var JsonString = response.Content.ReadAsStringAsync();
                // Deserialise the data (include the Newtonsoft JSON Nuget package if you don't already have it)
                //List<Claim> deserialized = JsonConvert.DeserializeObject<List<Claim>>(JsonString.Result);
                List<ClaimRootObject> deserialized = JsonConvert.DeserializeObject<List<ClaimRootObject>>(JsonString.Result);
    
                if (deserialized != null)
                {
                    return deserialized;
                }
            }
            else
            {
    
            }
        }
        return null;
    }
    
  3. Создание необходимых объектов

    
    public class ClaimRootObject
    {
        public string issuer { get; set; }
        public string originalIssuer { get; set; }
        public Properties properties { get; set; }
        public Subject subject { get; set; }
        public string type { get; set; }
        public string value { get; set; }
        public string valueType { get; set; }
    }
    public class Properties
    {
    }
    public class Subject
    {
        public string authenticationType { get; set; }
        public bool isAuthenticated { get; set; }
        public object actor { get; set; }
        public object bootstrapContext { get; set; }
        public List claims { get; set; }
        public object label { get; set; }
        public string name { get; set; }
        public string nameClaimType { get; set; }
        public string roleClaimType { get; set; }
    }
    
  4. И последний шаг,измените класс запуска проекта Web.Mvc, чтобы включить проверку подлинности cookie.


    public IServiceProvider ConfigureServices(IServiceCollection services)
        {
            // MVC
            services.AddMvc(
                options => options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute())
            );

            #region cookieAuthentication
            services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie();
            #endregion cookieAuthentication

            IdentityRegistrar.Register(services);
            AuthConfigurer.Configure(services, _appConfiguration);

            services.AddScoped();

            services.AddSignalR();

            // Configure Abp and Dependency Injection
            return services.AddAbp(
                // Configure Log4Net logging
                options => options.IocManager.IocContainer.AddFacility(
                    f => f.UseAbpLog4Net().WithConfig("log4net.config")
                )
            );
        }

Вот и все.Затем вы можете войти в приложение пользователя, используя только удаленные сервисы.

...