gpt4 book ai didi

c# web api 使用 auth1.0a 和 OAuthAuthorizationServerProvider

转载 作者:太空狗 更新时间:2023-10-29 20:38:24 26 4
gpt4 key购买 nike

我刚才使用 OAuthAuthorizationServerProvider 设置了基于 JWT token 的身份验证。提供者看起来像这样:

public class OAuthProvider : OAuthAuthorizationServerProvider
{

// Private properties
private readonly IAdvancedEncryptionStandardProvider _helper;
private readonly IUserProvider _userProvider;

// Optional fields
private readonly Lazy<IClientService> _clientService;

/// <summary>
/// Default constructor
/// </summary>
/// <param name="helper"></param>
public OAuthProvider(IAdvancedEncryptionStandardProvider helper, IUserProvider userProvider, Lazy<IClientService> clientService)
{
_helper = helper;
_userProvider = userProvider;
_clientService = clientService;
}

/// <summary>
/// Always validate the client because we are using angular
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
{

// Set up our variables
var clientId = string.Empty;
var clientSecret = string.Empty;
Client client = null;

// Try to get our credentials if basic authentication has been used
if (!context.TryGetBasicCredentials(out clientId, out clientSecret))
context.TryGetFormCredentials(out clientId, out clientSecret);

// If we have no client id
if (context.ClientId == null)
{
//Remove the comments from the below line context.SetError, and invalidate context
//if you want to force sending clientId/secrects once obtain access tokens.
context.Validated();
//context.SetError("invalid_clientId", "ClientId should be sent.");
return;
}

// Get our client
client = await _clientService.Value.GetAsync(context.ClientId);

// If we have no client, throw an error
if (client == null)
{
context.SetError("invalid_clientId", $"Client '{ context.ClientId }' is not registered in the system.");
return;
}

// Get the application type
if (client.ApplicationType == ApplicationTypes.NativeConfidential)
{

// If we have a client secret
if (string.IsNullOrWhiteSpace(clientSecret))
{
context.SetError("invalid_clientId", "Client secret shoud be sent.");
return;
}

if (client.Secret != _helper.Encrypt(clientSecret))
{
context.SetError("invalid_clientId", "Client secret is invalid.");
return;
}
}

// If the client is inactive, throw an error
if (!client.Active)
{
context.SetError("invalid_clientId", "Client is inactive.");
return;
}

// Set our allowed origin and token expiration
context.OwinContext.Set<string>("as:clientAllowedOrigin", client.AllowedOrigin);
context.OwinContext.Set<string>("as:clientRefreshTokenLifeTime", client.RefreshTokenLifeTime.ToString());

// Validate our request
context.Validated();
return;
}

/// <summary>
/// Authorize the request
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
// Set our allowed origin
var allowedOrigin = context.OwinContext.Get<string>("as:clientAllowedOrigin");
if (string.IsNullOrEmpty(allowedOrigin))
allowedOrigin = "*";

// Add our CORS
context.OwinContext.Response.Headers.Remove("Access-Control-Allow-Origin");
context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { allowedOrigin });

// Find user by username first
var user = await _userProvider.FindByNameAsync(context.UserName);

// If our user actually exists
if (user != null)
{

// Validate the users credentials
var validCredentials = await _userProvider.FindAsync(context.UserName, context.Password);
var lockoutEnabled = await _userProvider.GetLockoutEnabledAsync(user.Id);

// If lockout is enabled
if (lockoutEnabled)
{

// If the user entered invalid credentials
if (validCredentials == null)
{

// Record the failure which also may cause the user to be locked out
await _userProvider.AccessFailedAsync(user);

// Find out how many attempts are left
var accessFailedCount = await _userProvider.GetAccessFailedCountAsync(user.Id);
var attemptsLeft = Convert.ToInt32(ConfigurationManager.AppSettings["MaxFailedAccessAttemptsBeforeLockout"].ToString()) - accessFailedCount;

// Inform the user of the error
context.SetError("invalid_grant", string.Format(Resources.PasswordInvalid, attemptsLeft));
return;
}

// Check to see if the user is already locked out
var lockedOut = await _userProvider.IsLockedOutAsync(user.Id);

// If the user is lockted out
if (lockedOut)
{

// Inform the user
context.SetError("invalid_grant", string.Format(Resources.UserLocked, ConfigurationManager.AppSettings["DefaultAccountLockoutTimeSpan"].ToString()));
return;
}

// If we get this far, reset the access attempts
await _userProvider.ResetAccessFailedCountAsync(validCredentials);
}

// If the user entered the correct details
if (validCredentials != null)
{

// If the user has not confirmed their account
if (!validCredentials.EmailConfirmed)
{

// Inform the user
context.SetError("invalid_grant", Resources.UserHasNotConfirmed);
return;
}

// Generate our identity
var oAuthIdentity = await _userProvider.CreateIdentityAsync(validCredentials, "JWT");
oAuthIdentity.AddClaims(ExtendedClaimsProvider.GetClaims(validCredentials));

// Create our properties
var properties = new AuthenticationProperties(new Dictionary<string, string>
{
{"as:client_id", string.IsNullOrEmpty(context.ClientId) ? string.Empty : context.ClientId},
{"userName", context.UserName}
});

// Create our ticket and authenticate the user
var ticket = new AuthenticationTicket(oAuthIdentity, properties);
context.Validated(ticket);
return;
}
}

// Failsafe
context.SetError("invalid_grant", Resources.UserOrPasswordNotFound);
return;
}

/// <summary>
/// Adds additional properties to the response
/// </summary>
/// <param name="context">The current context</param>
/// <returns></returns>
public override Task TokenEndpoint(OAuthTokenEndpointContext context)
{
foreach (KeyValuePair<string, string> property in context.Properties.Dictionary)
context.AdditionalResponseParameters.Add(property.Key, property.Value);

return Task.FromResult<object>(null);
}

/// <summary>
/// Grants a refresh token for the current context
/// </summary>
/// <param name="context">The current context</param>
/// <returns></returns>
public override Task GrantRefreshToken(OAuthGrantRefreshTokenContext context)
{

// Get our client ids
var originalClient = context.Ticket.Properties.Dictionary["as:client_id"];
var currentClient = context.ClientId;

// If we are not the same client
if (originalClient != currentClient)
{

// Set the error and exit the function
context.SetError("invalid_clientId", "Refresh token is issued to a different clientId.");
return Task.FromResult<object>(null);
}

// Change auth ticket for refresh token requests
var newIdentity = new ClaimsIdentity(context.Ticket.Identity);

newIdentity.AddClaim(new Claim("newClaim", "newValue"));

var newTicket = new AuthenticationTicket(newIdentity, context.Ticket.Properties);
context.Validated(newTicket);

return Task.FromResult<object>(null);
}
}

这很有效,而且大部分情况下都很好。我的经理现在如何要求我使用keysecret 对其他应用程序进行身份验证。我想使用 OAuthAuthorizationServerProvider 来执行此操作,但我无法在任何地方找到有关如何进行设置的任何文档。

我已经阅读并找到了一种可以覆盖的方法:GrantCustomExtension 并认为也许我可以使用它来设置身份验证,但就像我提到的那样,我不知道如何设置它上。

有没有人有这方面的经验?如果有,他们能否通过提供代码示例或提供指向我可以阅读的资源的链接来帮助我?任何帮助将不胜感激。

最佳答案

我建议远离 Asp.net Identity 并使用 IdentityServer .

IdentityServer4 是一个用于 ASP.NET Core 的 OpenID Connect 和 OAuth 2.0 框架。IdentityServer3 适用于 Asp.Net Classic(尽管您可以将 IdentityServer4 与 Asp.net classic 一起使用)

它真的很容易配置,而且是非常持续的项目。

它有几个特点,比如

  1. 身份验证即服务
  2. 单点登录/注销
  3. API 访问控制
  4. 联合网关

最重要的是,它是免费和开源的。

关于c# web api 使用 auth1.0a 和 OAuthAuthorizationServerProvider,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45737280/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com