using IdentityModel; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Options; using System; using System.Collections.Generic; using System.Linq; using System.Security.Claims; using System.Text; using System.Threading.Tasks; using TEAMModelOS.Model.Core.Dtos; using TEAMModelOS.Model.Core.Models; using TEAMModelOS.SDK.Context.Configuration; using TEAMModelOS.SDK.Context.Constant.Common; using TEAMModelOS.SDK.Context.Exception; using TEAMModelOS.SDK.Extension.DataResult.JsonRpcRequest; using TEAMModelOS.SDK.Extension.DataResult.JsonRpcResponse; using TEAMModelOS.SDK.Extension.HttpClient.Implements; using TEAMModelOS.SDK.Extension.JwtAuth.JwtHelper; using TEAMModelOS.SDK.Extension.JwtAuth.Models; using TEAMModelOS.SDK.Helper.Common.CollectionHelper; using TEAMModelOS.SDK.Helper.Common.DateTimeHelper; using TEAMModelOS.SDK.Helper.Common.JsonHelper; using TEAMModelOS.SDK.Helper.Network.HttpHelper; using TEAMModelOS.SDK.Helper.Security.BCryptHelper; using TEAMModelOS.SDK.Module.AzureTable.Interfaces; using TEAMModelOS.Service.Core.Interfaces; namespace TEAMModelOS.Service.Core.Implements { public class LoginInfoService : ILoginInfoService { private IAzureTableDBRepository _repository; private IOptions _options; private IHttpContextAccessor _httpContextAccessor; private HttpClientUserInfo _httpClientService; public LoginInfoService(IAzureTableDBRepository repository, IOptions options, IHttpContextAccessor httpContextAccessor , HttpClientUserInfo httpClientService) { _httpContextAccessor = httpContextAccessor; _options = options; _repository = repository; _httpClientService = httpClientService; } public async Task CheckLoginAsync(TicketInfo ticketInfo) { string jtoken = HttpContextHelper.GetValueInHttp(_httpContextAccessor.HttpContext.Request, Constants.AUTHORIZATION); if (string.IsNullOrEmpty(ticketInfo.Token)) { LoginResult result = new LoginResult(); if (string.IsNullOrEmpty(ticketInfo.Ticket)) { result.CheckTicket = false; return result; } string code = BCryptHelper.Ecrypt(ticketInfo.Ticket + ticketInfo.TeamModelId); bool f = BCryptHelper.Verify(ticketInfo.Ticket + ticketInfo.TeamModelId, ticketInfo.Sign); LoginInfo login = _repository.FindOneByKey("Ticket", ticketInfo.Ticket).Result; if (login != null && !string.IsNullOrEmpty(login.Token)) { result.CheckTicket = true; JwtResponse token = await CreateJwtToken(login); result.JwtToken = token; login.Token = token.Access_token; result.JwtToken.Scope = login.Scope; await _repository.Update(login); return result; } JosnRPCRequest> request = new JosnRPCRequest> { method = "UserInfo" }; Dictionary ticket = new Dictionary { { "ticket", ticketInfo.Ticket } }; request.@params = ticket; string data = MessagePackHelper.ObjectToJson(request); string jsonStr = _httpClientService.HttpPost(BaseConfigModel.Configuration["HaBookAuth:AccountUrl"], data, Constants.CONTENT_TYPE_JSON, Encoding.UTF8); if (!string.IsNullOrEmpty(jsonStr)) { JosnRPCResponse response = MessagePackHelper.JsonToObject>(jsonStr); if (response.error == null && response != null) { result.CheckTicket = true; LoginInfo loginInfo = new LoginInfo { PartitionKey = response.result.cellphone, Phone = response.result.cellphone, RowKey = Guid.NewGuid().ToString(), TeamModelId = response.result.id, Name = response.result.name, Ticket = ticketInfo.Ticket, CountryCode = response.result.countryCode }; TeamModelUser user= await _repository.FindOneByKey("TeamModelId", response.result.id); if (user == null || string.IsNullOrEmpty(user.RowKey)) { user = new TeamModelUser { RowKey = Guid.NewGuid().ToString(), PartitionKey = loginInfo.CountryCode ,RegisterTime=DateTimeHelper.ConvertToTimeStamp13(DateTime.Now) }; } user.Cellphone = response.result.cellphone; user.NickName = response.result.name; if (string.IsNullOrEmpty(user.FullName)) { user.FullName = response.result.name; } user.TeamModelId = response.result.id; user.CountryCode = response.result.countryCode; JwtResponse jwtToken = await CreateJwtToken(loginInfo); loginInfo.Token = jwtToken.Access_token; loginInfo.Scope = jwtToken.Scope; result.JwtToken = jwtToken; await _repository.Save(loginInfo); await _repository.SaveOrUpdate(user); return result; } else { result.CheckTicket = false; return result; } } else { result.CheckTicket = false; return result; } } else { ClaimModel claimModel = JwtHelper.SerializeJWT(ticketInfo.Token); var dateTime = DateTimeHelper.ConvertToTimeStamp10(DateTime.Now); var expExt=claimModel.Claim.TryGetValue("exp",out var exp); if (expExt==false || dateTime > long.Parse(exp.ToString())) { throw new BizException(401, "Unauthorized"); } Dictionary msp = new Dictionary { { "Token", ticketInfo.Token } }; LoginInfo loginInfo = _repository.FindOneByDict(msp).Result; if (loginInfo != null && !string.IsNullOrEmpty(loginInfo.Token)) { return new LoginResult { JwtToken = new JwtResponse { Access_token=loginInfo.Token ,Scope=loginInfo.Scope}, CheckTicket = true }; } else { throw new BizException(401, "Unauthorized"); } } } public async Task CreateJwtToken(LoginInfo loginInfo) { Dictionary dict = new Dictionary { { "Phone", loginInfo.CountryCode + loginInfo.Phone }, { "TeamModelId", loginInfo.TeamModelId } }; string role = ""; List roleUsers = await _repository.FindListByDict(dict); if (roleUsers.IsNotEmpty()) { foreach (RoleUser roleUser in roleUsers) { role = role + roleUser.RoleCode + ","; } } role= role.Substring(0, role.Length - 1); ClaimModel model = new ClaimModel { Scope = "WebApp" }; model.Claims.Add(new Claim(JwtClaimTypes.Name, loginInfo.Name)); model.Claims.Add(new Claim(JwtClaimTypes.Id, loginInfo.TeamModelId)); ////保护隐私 //model.Claims.Add(new Claim(JwtClaimTypes.PhoneNumber, loginInfo.Phone)); model.Claims.AddRange(role.Split(',').Select(s => new Claim(JwtClaimTypes.Role, s))); model.Roles.Add(role); JwtResponse jwtResponse = JwtHelper.IssueJWT(model, _options.Value); return jwtResponse; } public Task SaveLoginInfoAsync(LoginInfo loginInfo) { return _repository.Save(loginInfo); } } }