ABP-VNext 用户权限管理系统实战05---单点登录
一、应用场景:
公司开发的业务系统常常要集成到其它的业务系统中,在其它的业务系统通过一个连接点击就可进入自己的系统,连接组成:http:192.168.18.17:8088?username=xxxxxx
当然用户名可能是加密的,需要解密,但是最后用户名都是我们系统自己的用户名.
二、功能开发:
1、增加一种客户端myClient,支持用户名登录
2、注入用户名扩展类:UserNameGrantValidator
3、在UserNameGrantValidator扩展类中验证用户名
public class UserNameGrantValidator : IExtensionGrantValidator
{
public string GrantType => "username";
//1q2w3e* 进行sha256编码后结果
public string ClientSecret => "E5Xd4yMqjP5kjWFKrYgySBju6JVfCzMyFp7n2QmMrME=";
private readonly UserManager<Volo.Abp.Identity.IdentityUser> _usermanager;
private readonly IdentityUserManager _identityUserManager;
private readonly IConfiguration _configuration;
public UserNameGrantValidator(UserManager<Volo.Abp.Identity.IdentityUser> usermanager, IdentityUserManager identityUserManager, IConfiguration configuration)
{
_configuration = configuration;
_usermanager = usermanager;
this._identityUserManager = identityUserManager;
}
public Task ValidateAsync(ExtensionGrantValidationContext context)
{
var username = context.Request.Raw.Get("username");
var auth_code = context.Request.Raw.Get("client_key");
var authcodeconfig = _configuration["ClientAuthKey"];
if (string.IsNullOrEmpty(auth_code) || string.IsNullOrEmpty(authcodeconfig) || auth_code != authcodeconfig.Sha256())
{
context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, "客户端授权码无效");
return Task.FromResult(1);
}
//var user = _userRepository.FirstOrDefaultAsync(x => x.Name == username);
var user = _usermanager.FindByNameAsync(username).Result;
if (user == null)
{
context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, "用户未注册");
return Task.FromResult(1);
}
//var claims = new List<Claim>();
//foreach (var itemClaim in user.Result.Claims)
//{
// var claim = new Claim(itemClaim.ClaimType, itemClaim.ClaimValue);
// claims.Add(claim);
//}
context.Result = new GrantValidationResult(
subject: user.Id.ToString(),
authenticationMethod: GrantType);
return Task.FromResult(0);
}
}
4、登录接口,获取token
/// <summary>
/// 登录
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
public async Task<ResponseResult<LoginOutput>> SSOLogin(LoginInput input)
{
//查询用户名是否存在
IdentityUser user = await _userRepository.FirstOrDefaultAsync(s => s.UserName == input.UserName.Trim());
if (user == null)
{
return ResponseResult<LoginOutput>.Fail("用户名不存在!");
}
var client = new HttpClient();
//var clientScope = string.Join(" ", _serviceScope);
var parameters = new Parameters();
parameters.Add("username", input.UserName);
parameters.Add("client_key", input.ClientAuthKey);
var tokenResponse = await client.RequestTokenAsync(new TokenRequest
{
Address = $"{_config["AuthServer:Authority"]}/connect/token",
ClientId = "myClient",
ClientSecret = "1q2w3e*",
GrantType = "username",
Parameters = parameters,
});
LoginOutput loginOutput = new LoginOutput()
{
LoginResult = LoginResultEnum.Success,
Token = tokenResponse.AccessToken,
RefreshToken = tokenResponse.RefreshToken,
UserName = user.UserName
};
return ResponseResult<LoginOutput>.Success("登录成功", loginOutput);
}
5、获取token的结果