Commit 525791d7 by gzq

CAS单点登陆

parent d80ba249
......@@ -2,8 +2,10 @@
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using AngleSharp.Dom;
using FluentValidation.AspNetCore;
using GSS.Authentication.CAS.Validation;
using MassTransit.Internals.Extensions;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
......@@ -26,13 +28,15 @@ public class AccountController : Controller
private Application _options;
private ClaimService _claim;
private HospitalService _hospitalService;
private CasOptionss _casOptions;
public AccountController(UserService userService,
HospitalService hospitalService,
RoleService roleService,
IMemoryCache memoryCache,
IOptions<Application> options,
ClaimService claim)
ClaimService claim,
CasOptionss casOptions)
{
_userService = userService;
_roleService = roleService;
......@@ -40,6 +44,7 @@ public class AccountController : Controller
_hospitalService = hospitalService;
_options = options.Value;
_claim = claim;
_casOptions = casOptions;
}
/// <summary>
......@@ -95,6 +100,81 @@ public ApiResponse<JwtToken> Login([FromBody] LoginRequest request)
}
/// <summary>
/// CAS 单点登录
/// </summary>
/// <returns></returns>
[HttpGet]
[Route("CasLogin")]
[AllowAnonymous]
public IActionResult CasLogin()
{
var casServerUrl = _casOptions.CasServerUrlBase;
var casServerUr2 = _casOptions.ServerName;
var returnUrl = $"{casServerUrl}?service={Uri.EscapeDataString(casServerUr2)}";
var response = new ApiResponse
{
State = ResponseType.OK,
Message = "OK",
Data = new DataItem { Url = returnUrl }
};
return Ok(response);
}
/// <summary>
/// CAS 回调验证方法
/// </summary>
/// <param name="ticket">cas验证票据</param>
/// <param name="casOptionsAccessor"></param>
/// <returns></returns>
[HttpGet]
[Route("CasCallbackAsync")]
[AllowAnonymous]
public async Task<IActionResult> CasCallbackAsync(string ticket, [FromServices] IOptions<CasOptionss> casOptionsAccessor)
{
var casOptions = casOptionsAccessor.Value;
var serviceUrl = casOptions.ServerName;
if (ticket != null)
{
// 验证票据
var cas30TicketValidator = new Cas30ServiceTicketValidator(casOptions);
var validation = await cas30TicketValidator.ValidateAsync(ticket, serviceUrl);
if (validation != null)
{
//查询CAS认证用户
var user = _userService.GetEntityUser(validation.Assertion.PrincipalName);
if (user == null)
{
_userService.CasInsertUser(validation.Assertion.PrincipalName);
user = _userService.GetEntityUser(validation.Assertion.PrincipalName);
}
var claims = new Claim[]
{
new Claim(JwtClaimTypes.Id, user.ID.ToString()),
new Claim(JwtClaimTypes.Login, user.Login),
new Claim(JwtClaimTypes.RealName, user.RealName),
new Claim(JwtClaimTypes.Mail, user.Mail??""),
new Claim(JwtClaimTypes.Department, user.Department ?? ""),
};
//Token认证
var jwtToken = JwtTokenHelper.GenerateToken(claims, _options.ExpirationMinutes);
return Ok(new ApiResponse<JwtToken>(ResponseType.OK, jwtToken));
}
else
{
return BadRequest("CAS票据验证失败。你的账户可能无效。");
}
}
else
{
return BadRequest("CAS票据为空。你的账户可能无效。");
}
}
/// <summary>
/// 快速登录
/// </summary>
/// <param name="request"></param>
......
......@@ -41,6 +41,8 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="AspNetCore.Security.CAS" Version="2.0.5" />
<PackageReference Include="GSS.Authentication.CAS.AspNetCore" Version="5.4.0" />
<PackageReference Include="XC.RSAUtil" Version="1.3.6" />
</ItemGroup>
......
......@@ -2,10 +2,12 @@
using System.Globalization;
using System.Reflection;
using System.Text;
using AspNetCore.Security.CAS;
using AspNetCoreRateLimit;
using FluentScheduler;
using FluentValidation;
using FluentValidation.AspNetCore;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
......@@ -16,6 +18,7 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Performance.Api.Configurations;
using Performance.DtoModels;
using Performance.Infrastructure;
using Performance.Services;
......@@ -44,6 +47,17 @@ public void ConfigureServices(IServiceCollection services)
// graphql
services.AddGraphQLSchemaAndTypes();
services.Configure<CasOptionss>(Configuration.GetSection("CasOptionss"));
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCAS(option =>
{
// 从配置文件读取 CAS 设置
IConfigurationSection casSettings = Configuration.GetSection("CasOptionss");
option.CasServerUrlBase = casSettings["CasServerUrlBase"];
option.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
});
#region json & fluentvalidation & filter
services
......
......@@ -47,5 +47,19 @@
],
"Period": "1", // 单位为秒
"Limit": 1
},
"CasOptionss": {
"CasServerUrlBase": "http://192.168.9.50:30080/cas",
"CasServerUrlPrefix": "http://192.168.9.50:30080/cas",
"ServerName": "http://192.168.9.66:8090",
"RedirectAfterValidation": true,
"Gateway": false,
"Renew": false,
"SingleSignOut": true,
"TicketTimeTolerance": 5000,
"TicketValidatorName": "Cas20",
"ProxyTicketManager": "CacheProxyTicketManager",
"ServiceTicketManager": "CacheServiceTicketManager",
"GatewayStatusCookieName": "CasGatewayStatus"
}
}
using GSS.Authentication.CAS;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Performance.DtoModels
{
/// <summary>
/// CAS 配置
/// </summary>
public class CasOptionss : ICasOptions
{
/// <summary>
/// CAS服务器的基础URL
/// </summary>
public string CasServerUrlBase { get; set; }
/// <summary>
/// 当前应用的URL,用于构建回调URL
/// </summary>
public string ServerName { get; set; }
/// <summary>
/// 是否启用CAS单点登录
/// </summary>
public bool EnableSso { get; set; } = true;
/// <summary>
/// CAS
/// </summary>
public string AuthenticationType { get; set; } = CasDefaults.AuthenticationType;
/// <summary>
/// CAS版本
/// </summary>
public CasProtocolVersion ProtocolVersion { get; set; } = CasProtocolVersion.V3;
}
public class DataItem
{
public string Url { get; set; }
}
}
......@@ -20,6 +20,13 @@ public enum States
Disabled = 2,
}
public enum CasProtocolVersion
{
V1,
V2,
V3
}
/// <summary> 提取数据使用模板 </summary>
public enum UseTemplate
{
......
......@@ -10,6 +10,11 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="AspNetCore.Security.CAS" Version="2.0.5" />
<PackageReference Include="GSS.Authentication.CAS.AspNetCore" Version="5.4.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Performance.EntityModels\Performance.EntityModels.csproj" />
<ProjectReference Include="..\Performance.Infrastructure\Performance.Infrastructure.csproj" />
</ItemGroup>
......
......@@ -83,6 +83,48 @@ public UserIdentity Login(LoginRequest request)
throw new PerformanceException($"登录类型LoginType:{request.LoginType}暂不支持");
}
/// <summary>
/// 新增用户
/// </summary>
/// <param name="userName">用户名</param>
public UserResponse CasInsertUser(string userName)
{
// 检查用户名是否重复
if (_userRepository.GetEntity(t => t.Login == userName && (t.ParentID == null || t.ParentID == 0) && t.IsDelete == 1) != null)
throw new PerformanceException("登录名重复");
string nPassword = "123456";
var user = new sys_user
{
Login = userName,
CreateDate = DateTime.Now,
CreateUser = 0,
Password = PwdHelper.MD5AndSalt(nPassword),
RealName = userName,
States = (int)States.Enabled,
IsDelete = 1
};
if (!_userRepository.Add(user))
throw new PerformanceException("保存失败");
_userroleRepository.Add(new sys_user_role { UserID = user.ID, RoleID = (int)Role.绩效查询 });
_userhospitalRepository.Add(new sys_user_hospital { UserID = user.ID, HospitalID = 1 });
return _mapper.Map<UserResponse>(user);
}
/// <summary>
/// 查询用户
/// </summary>
/// <param name="userName"></param>
/// <returns></returns>
public sys_user GetEntityUser(string userName)
{
var users = _userRepository.GetEntities();
return users.Find(w => w.Login.Contains(userName));
}
public UserIdentity GetUser(int userId)
{
var user = _userRepository.GetEntity(t => t.ID == userId);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment