IdentityServer4 实现自定义 GrantType 授权模式
OAuth 2.0 默认四种授权模式(GrantType)
- 授权码模式(authorization_code)
- 简化模式(implicit)
- 密码模式(password)
- 客户端模式(client_credentials)
1.使用 IdentityServer4,我们可以自定义授权模式
例如:自定义sms_auth_code
授权模式
using IdentityServer4;
using IdentityServer4.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace User.Identity
{
public class IdentityServerConfig
{
/// <summary>
/// Client
/// </summary>
/// <returns></returns>
public static IEnumerable<Client> GetClients()
{
return new List<Client>
{
//new Client{
// ClientId = "iphone",
// ClientSecrets = new List<Secret>
// {
// new Secret("secret".Sha256())
// },
// RefreshTokenExpiration = TokenExpiration.Sliding,
// AllowOfflineAccess = true,
// RequireClientSecret = false,
// AllowedGrantTypes = new List<string>{ "sms_auth_code"},
// AlwaysIncludeUserClaimsInIdToken = true,
// AllowedScopes = new List<string>{
// "finbook_api",
// IdentityServerConstants.StandardScopes.OpenId,
// IdentityServerConstants.StandardScopes.Profile,
// IdentityServerConstants.StandardScopes.OfflineAccess
// }
//}
new Client{
ClientId = "android",
ClientSecrets = new List<Secret>{ new Secret("secret".Sha256())},
AllowedGrantTypes = new List<string>{ "sms_auth_code" },
AllowedScopes = { "user_api" }
}
};
}
/// <summary>
/// Identity Resources
/// </summary>
/// <returns></returns>
public static IEnumerable<IdentityResource> GetIdentityResources()
{
return new List<IdentityResource> {
new IdentityResources.OpenId(),
new IdentityResources.Profile()
};
}
/// <summary>
/// API Resource
/// </summary>
/// <returns></returns>
public static IEnumerable<ApiResource> GetApiResources()
{
return new List<ApiResource> {
new ApiResource("user_api","用户API")
};
}
}
}
2.自定义类需要继承using IdentityServer4.Validation
下的IExtensionGrantValidator
接口
using IdentityServer4.Models;
using IdentityServer4.Services;
using IdentityServer4.Validation;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using User.Identity.Services;
namespace User.Identity.Authentication
{
public class SmsAuthCodeValidator : IExtensionGrantValidator
{
public string GrantType => "sms_auth_code";
public readonly IAuthCodeService _authCodeService;
public readonly IUserService _userService;
public SmsAuthCodeValidator(IAuthCodeService authCodeService, IUserService userService) {
_authCodeService = authCodeService;
_userService = userService;
}
public async Task ValidateAsync(ExtensionGrantValidationContext context)
{
var phone = context.Request.Raw["phone"];
var authcode = context.Request.Raw["sms_auth_code"];
var errorValidateResult = new GrantValidationResult(TokenRequestErrors.InvalidGrant);
if (!string.IsNullOrEmpty(phone) || !string.IsNullOrEmpty(authcode))
{
context.Result = errorValidateResult;
return;
}
//校验验证码
if (!_authCodeService.Validate(phone,authcode))
{
context.Result = errorValidateResult;
return;
}
//校验手机号是否存在,
var userid =await _userService.CheckOrCreateAsync(phone);
if (userid<=0)
{
context.Result = errorValidateResult;
return;
}
context.Result = new GrantValidationResult(userid.ToString(),GrantType);
}
}
}
3.在Startup.cs
里Configuration
的配置如下
public void ConfigureServices(IServiceCollection services)
{
//配置Identity Server
var builder = services.AddIdentityServer()
.AddDeveloperSigningCredential()
.AddInMemoryIdentityResources(IdentityServerConfig.GetIdentityResources())
.AddInMemoryApiResources(IdentityServerConfig.GetApiResources())
.AddInMemoryClients(IdentityServerConfig.GetClients())
.AddExtensionGrantValidator<SmsAuthCodeValidator>()//IdentityServer自定义验证
;
//依赖注入
services.AddScoped<IAuthCodeService, AuthCodeService>()
.AddScoped<IUserService, UserService>()
.AddSingleton<HttpClient>();
services.AddControllers();
}