2024-11-26 16:09查看470评论0
authorization_code 授权码 认证流程如下
今天着重讲一下关于authorization_code 授权码认证的 C# WebApi 实现过程
StartUp.cs 配置认证接口
public void Configuration(IAppBuilder app)
{
HttpConfiguration configuration = new HttpConfiguration();
WebApiConfig.Register(configuration);
OAuthAuthorizationServerOptions options = new OAuthAuthorizationServerOptions()
{
AllowInsecureHttp = false,
AuthenticationMode = AuthenticationMode.Active,
AuthorizeEndpointPath = new PathString("/oauth2"),
TokenEndpointPath = new PathString(value: "/access_token"),
AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(30),
Provider = new OpenAuthorizationServerProvider(),
AuthorizationCodeProvider = new OpenAuthorizationCodeProvider(),
RefreshTokenProvider = new OpenRefreshTokenProvider(),
};
configuration.Formatters.JsonFormatter.SerializerSettings = new Newtonsoft.Json.JsonSerializerSettings()
{
ContractResolver = new CamelCasePropertyNamesContractResolver(),
DateFormatString = "yyyy-MM-dd HH:mm:ss"
};
app.UseOAuthAuthorizationServer(options);
app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
app.UseCors(CorsOptions.AllowAll);
app.UseWebApi(configuration);
}
OpenAuthorizationServerProvider 需要继承 OAuthAuthorizationServerProvider 实现如下
public class OpenAuthorizationServerProvider : OAuthAuthorizationServerProvider
{
public override Task ValidateClientRedirectUri(OAuthValidateClientRedirectUriContext context)
{
context.Validated(context.RedirectUri);
return base.ValidateClientRedirectUri(context);
}
public override async Task ValidateAuthorizeRequest(OAuthValidateAuthorizeRequestContext context)
{
if (context.AuthorizeRequest.ClientId.StartsWith("appidstr"))
{
await Task.Run(() => { context.Validated();});
}
else
{
await Task.Run(() => { context.Rejected(); });
}
}
public override async Task AuthorizeEndpoint(OAuthAuthorizeEndpointContext context)
{
var redirectUri = context.Request.Query["redirect_uri"];
var clientId = context.Request.Query["client_id"];
var identity = new ClaimsIdentity(new GenericIdentity(clientId,OAuthDefaults.AuthenticationType));
var authorizeCodeContext = new AuthenticationTokenCreateContext(context.OwinContext,context.Options.AuthorizationCodeFormat,new AuthenticationTicket(identity,new AuthenticationProperties(new Dictionary<string, string>{{"client_id", clientId},{"redirect_uri", redirectUri}}){IssuedUtc = DateTimeOffset.UtcNow,ExpiresUtc = DateTimeOffset.UtcNow.Add(context.Options.AccessTokenExpireTimeSpan)}));
await context.Options.AuthorizationCodeProvider.CreateAsync(authorizeCodeContext);
context.Response.Redirect(redirectUri + "?code=" + Uri.EscapeDataString(authorizeCodeContext.Token));
context.RequestCompleted();
}
public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
{
string clientId, clientSecret;
context.TryGetFormCredentials(out clientId, out clientSecret);
if (!clientId.StartsWith("appidstr"))
{
context.SetError("invalid_client", "未授权的客户端");
return Task.FromResult<object>(null); ;
}
context.Validated();
return Task.FromResult<object>(null);
}
public override Task GrantClientCredentials(OAuthGrantClientCredentialsContext context)
{
return base.GrantClientCredentials(context);
}
public override Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
ClaimsIdentity identity = new GenericIdentity(name: context.ClientId, type: OAuthDefaults.AuthenticationType);
int userid = 13;
string role = "管理员";
string scope = "权限1,权限2";
identity.AddClaim(new Claim("userid", userid.ToString()));
identity.AddClaim(new Claim("role", role));
identity.AddClaim(new Claim("scope", scope));
context.Validated(identity);
return base.GrantResourceOwnerCredentials(context);
}
public override async Task ValidateTokenRequest(OAuthValidateTokenRequestContext context)
{
if (context.TokenRequest.IsAuthorizationCodeGrantType)
{
await Task.Run(()=>{context.Validated();});
}
else
{
await Task.Run(()=>{context.Rejected();});
}
}
}
PostMan 提交参数 第一步获取 code
第二步,通过 code 换取接口调用凭证 access_token
至此,就完成了 授权码模式的oAuth2认证,当然 access_token 需要客户端保存,根据 expires_in 过期时间刷新,来维持资源访问会话授权。