一、應用場景:
公司開發的業務系統常常要集成到其它的業務系統中,在其它的業務系統通過一個連接點擊就可進入自己的系統,連接組成: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的結果