abp vnext6.0之后官方替换了原来的ids4,采用了openIddict的oauth认证框架。使用之前的方法已经不行,以下是OpenIddect 使用ITokenExtensionGrant接口进行的授权登入扩展,按照以下代码可实现,欢迎交流指正。
新建用于接收微信返回数据字段类
public class Results
{
/// <summary>
/// 用户唯一标识
/// </summary>
public string openid { get; set; }
/// <summary>
/// 会话密钥
/// </summary>
public string session_key { get; set; }
/// <summary>
/// 用户在开放平台的唯一标识符,若当前小程序已绑定到微信开放平台帐号下会返回
/// </summary>
public string unionid { get; set; }
/// <summary>
/// 错误码
/// </summary>
public int errcode { get; set; }
/// <summary>
/// 错误信息
/// </summary>
public string errmsg { get; set; }
}
在HttpApi.Host新建类
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using OpenIddict.Abstractions;
using OpenIddict.Server.AspNetCore;
using System.Collections.Generic;
using System.Net.Http;
using System.Security.Claims;
using System.Text.Json;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
using Volo.Abp.OpenIddict.Controllers;
using Volo.Abp.OpenIddict.ExtensionGrantTypes;
namespace Demo
{
[IgnoreAntiforgeryToken]
[ApiExplorerSettings(IgnoreApi = true)]
public class TokenExtensionGrant : AbpOpenIdDictControllerBase, ITokenExtensionGrant
{
protected IOptions<IdentityOptions> IdentityOptions => LazyServiceProvider.LazyGetRequiredService<IOptions<IdentityOptions>>();
public const string ExtensionGrantName = "wechat_code";
public string Name => ExtensionGrantName;
public async Task<IActionResult> HandleAsync(ExtensionGrantContext context)
{
LazyServiceProvider = context.HttpContext.RequestServices.GetRequiredService<IAbpLazyServiceProvider>();
string code = context.Request.GetParameter("code").ToString();
if (string.IsNullOrEmpty(code))
{
return NewForbidResult("code参数为空!");
}
var results = GetResults(context, code);
switch (results.errcode)
{
case 0:
string providerKey = results.openid;
var claimsPrincipal = await ServerValidate(context, "wechat", providerKey);
return claimsPrincipal == null ?
RetForbidResult("未绑定微信")
:
SignIn(claimsPrincipal, OpenIddictServerAspNetCoreDefaults.AuthenticationScheme);
//可以自行根据微信返回错误代码进行相应的错误处理
default:
return NewForbidResult(results.errmsg);
}
}
private ForbidResult NewForbidResult(string msg)
{
return new ForbidResult(
new[] { OpenIddictServerAspNetCoreDefaults.AuthenticationScheme },
GetAuthenticationProperties(msg));
}
private AuthenticationProperties GetAuthenticationProperties(string msg)
{
return new AuthenticationProperties(new Dictionary<string, string>
{
[OpenIddictServerAspNetCoreConstants.Properties.Error] = OpenIddictConstants.Errors.InvalidRequest,
[OpenIddictServerAspNetCoreConstants.Properties.ErrorDescription] = msg
});
}
/// <summary>
/// 服务器验证
/// </summary>
/// <param name="context"></param>
/// <param name="loginProvider"></param>
/// <param name="providerKey"></param>
/// <returns></returns>
private async Task<ClaimsPrincipal> ServerValidate(ExtensionGrantContext context, string loginProvider, string providerKey)
{
await IdentityOptions.SetAsync();
var user = await UserManager.FindByLoginAsync(loginProvider, providerKey);
if (user == null)
{
return null;
}
var principal = await SignInManager.CreateUserPrincipalAsync(user);
var scopes = context.Request.GetScopes();
principal.SetScopes(scopes);
var resources = await GetResourcesAsync(scopes);
principal.SetResources(resources);
return principal;
}
/// <summary>
/// 根据code得到微信openid
/// </summary>
/// <param name="context"></param>
/// <param name="code"></param>
/// <returns></returns>
private Results GetResults(ExtensionGrantContext context, string code)
{
string _appid = "WeChat_appId";
string _secret = "WeChat_secret";
string url = string.Format(
"https://api.weixin.qq.com/sns/jscode2session?appid={0}&secret={1}&js_code={2}&grant_type=authorization_code",
_appid,
_secret,
code);
HttpClient client = new HttpClient();
HttpResponseMessage response = client.GetAsync(url).Result;
if (response.IsSuccessStatusCode)
{
string resContent = response.Content.ReadAsStringAsync().Result;
var results = JsonSerializer.Deserialize<Results>(resContent);
return results;
}
else
{
return new Results { errmsg = "微信接口请求失败" };
}
}
}
}
在HttpApiHostModule.cs 文件中添加注册
使用上面定义的ExtensionGrantName扩展的这个openiddict的认证流程的名字
public override void PreConfigureServices(ServiceConfigurationContext context)
{
///······
PreConfigure<OpenIddictServerBuilder>(builder =>
{
builder.Configure(options =>
{
options.GrantTypes.Add(Demo.ExtensionGrantName);
});
});
}
请求地址和参数
host:/connect/token
methon:POST
media type:aplication/x-www-form-urlencoded
body:
grant_type=wechat_code
code=微信小程序提供的code
client_id=自己项目的client_id
scope=自己项目 openid offline_access
钉钉可参考本文进行OpenIddect 扩展授权登录,欢迎交流指正,谢谢阅读。文章来源:https://www.toymoban.com/news/detail-686192.html
参考文章(感谢以下文章和作者):
【Abp vnext 6.0手机号验证码登录】【作者:瓦力】文章来源地址https://www.toymoban.com/news/detail-686192.html
到了这里,关于abp Vnext OpenIddect 扩展微信小程序授权登录的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!