I. Introduction
Previous I shared an article about the application Asp.Net Core IdentityServer4 authority in the real article, many of which bloggers give me a problem, which has a Friends of Bo asked me a scene, I give him answers is not perfect, then I learn through their own review and read the relevant source code and found that IdentityServer4
you can implement a custom GrantType
License.
Disclaimer : When reading this if you did not read my last Asp.Net Core application IdentityServer4 authority of the real article, please venue to see that the above article, this article will look clearer, thanks for the support ,Thanks for attention!
Second, the simulation scene
The article has put electricity supplier system upgrades from a single gateway architecture to a multi-gateway architecture, the architecture is as follows:
However, the above 授权中心
use is 密码授权模式
, but for 微信小程序
, 微信公众号商城
authorized end use is not very appropriate;
微信小程序
and 微信公众号
micro-mall client scenario is as follows:
the user access applets mall or micro-channel public number Mall will after 微信服务端
obtaining authorization to get the relevant user openId
, unionId
, userName
etc. related information, and then carry openId
, unionId
, userName
and other information access 授权中心
gateway, authorization, if it does not exist automatically registered users, if there is a successful login authorization and other operations. After this scene that I do to transform 授权中心
service gateway it? After research and discussion, I put the above Chart refined into a gateway architecture diagram below:
Third, the Authority upgrading
The last article of our solutions has been established in three projects:
Jlion.NetCore.Identity.Service
:授权中心
Gateway -WebApi
ProjectJlion.NetCore.Identity.UserApiService
:用户业务网关
-WebApi
ProjectJlion.NetCore.Identity
:基础类库
Mainly used for public infrastructure layer to put this one
Through the above demand scenario analysis, we present 授权中心
enough this demand, so we can IdentityServer4
to meet the needs of the scene above custom authorization way upgrading.
After viewing the source code I found that we can implement IExtensionGrantValidator
abstract interface to a custom authorization way to achieve and implement ValidateAsync
the method,
and now I'm in the solution prior to 授权中心
new projects in the WeiXinOpenGrantValidator
class code is as follows:
public class WeiXinOpenGrantValidator : IExtensionGrantValidator
{
public string GrantType => GrantTypeConstants.ResourceWeixinOpen;
public async Task ValidateAsync(ExtensionGrantValidationContext context)
{
try
{
#region 参数获取
var openId = context.Request.Raw[ParamConstants.OpenId];
var unionId = context.Request.Raw[ParamConstants.UnionId];
var userName = context.Request.Raw[ParamConstants.UserName];
#endregion
#region 通过openId和unionId 参数来进行数据库的相关验证
var claimList = await ValidateUserAsync(openId, unionId);
#endregion
#region 授权通过
//授权通过返回
context.Result = new GrantValidationResult
(
subject: openId,
authenticationMethod: "custom",
claims: claimList.ToArray()
);
#endregion
}
catch (Exception ex)
{
context.Result = new GrantValidationResult()
{
IsError = true,
Error = ex.Message
};
}
}
#region Private Method
/// <summary>
/// 验证用户
/// </summary>
/// <param name="loginName"></param>
/// <param name="password"></param>
/// <returns></returns>
private async Task<List<Claim>> ValidateUserAsync(string openId, string unionId)
{
//TODO 这里可以通过openId 和unionId 来查询用户信息(数据库查询),
//我这里为了方便测试还是直接写测试的openId 相关信息用户
var user = OAuthMemoryData.GetWeiXinOpenIdTestUsers();
if (user == null)
{
//注册用户
}
return new List<Claim>()
{
new Claim(ClaimTypes.Name, $"{openId}"),
};
}
#endregion
}
GrantTypeConstants
The code is static, mainly used to define GrantType
a custom authorization type, and more likely to follow the custom Authorization Therefore, there is a unified place to manage, easy to maintain, as follows:
public static class GrantTypeConstants
{
/// <summary>
/// GrantType - 微信端授权
/// </summary>
public const string ResourceWeixinOpen = "weixinopen";
}
ParamConstants
Class is the definition of the parameters required custom authorization code is as follows:
public class ParamConstants
{
public const string OpenId = "openid";
public const string UnionId = "unionid";
public const string UserName = "user_name";
}
Well above was custom validator has been achieved, but not enough, we need to let clients support the type of authorization custom, we open the OAuthMemoryData
code GetClients
, the code is as follows:
public static IEnumerable<Client> GetClients()
{
return new List<Client>
{
new Client()
{
ClientId =OAuthConfig.UserApi.ClientId,
AllowedGrantTypes = new List<string>()
{
GrantTypes.ResourceOwnerPassword.FirstOrDefault(),//Resource Owner Password模式
GrantTypeConstants.ResourceWeixinOpen,//新增的自定义微信客户端的授权模式
},
ClientSecrets = {new Secret(OAuthConfig.UserApi.Secret.Sha256()) },
AllowedScopes= {OAuthConfig.UserApi.ApiName},
AccessTokenLifetime = OAuthConfig.ExpireIn,
},
};
}
Client AllowedGrantTypes
Configuration Authorization I just added a custom GrantTypeConstants.ResourceWeixinOpen
,
now also support the client has been configured, and finally we need to AddExtensionGrantValidator<>
extend the method 自定义授权验证器
to register DI
, the code is as follows:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
#region 数据库存储方式
services.AddIdentityServer()
.AddDeveloperSigningCredential()
.AddInMemoryApiResources(OAuthMemoryData.GetApiResources())
//.AddInMemoryClients(OAuthMemoryData.GetClients())
.AddClientStore<ClientStore>()
.AddResourceOwnerValidator<ResourceOwnerPasswordValidator>()
.AddExtensionGrantValidator<WeiXinOpenGrantValidator>();
#endregion
}
Well, simple 授权中心
code upgrade has been completed, we are run from the command line 授权中心
and 用户业务网关
, before 用户业务网关
without changing any code, the diagram are as follows:
Jlion.NetCore.Identity.Server authority to run the following
Jlion.NetCore.Identity.UserApiServer user service gateway runs as follows
We now use simulation postman openId
, unionId
, userName
parameter request 授权中心
to obtain AccessToken
, following requests:
We have to carry authorization information accessed through the postman 用户业务网关
data, the result is as follows:
Well, custom licensing model has been completed, simply 授权中心
has the upgrade is complete, the above WeiXinOpenGrantValidator
validator I did not go directly to a database approach to authentication and registration, write a simple Demo, we are interested that the TODO fast database operation to achieve, I have submitted to the code on github, and here to share my blog address demo synchronous combat again https://github.com/a312586670/IdentityServerDemo
Fourth, thinking and summary
Benpian I introduced the custom Authorization, by looking at the source code and access to information learned IdentityServer4
can 自定义授权
be extended manner. This 授权中心
can be extended multiple sets of authorization methods, such as the sharing of custom micro letter today openId authorization, SMS verification codes and other authorized custom authorization, a Api资源
possible merger multiple sets of licensing models, flexible and scalable, flexible upgrade. Knowledge Benpian involved small, but very important, because we use 授权中心
often encounter with a variety of authentication methods, and different sets of user applications use a unified identity authentication, authorization mastered the principles of the can switching in a different way in the authorization capability, here some bloggers will ask AccentToken
an expiration time, will expire how to do? Do you want to re-authorize it, please? These issues I will arrange the next article to share.
Soul asked:
The above 授权中心
example is mainly to give you a better understanding of custom authorization of usage scenarios and its flexibility, the real scene so directly to openId
other relevant information to verify the authorization safe? Everyone may be thinking, what if we unsafe good solution? Self-improvement is to stop thinking for themselves, we can please play to their thinking, the answers remain in the message board, to learn for your reference, thanks! ! !