Функция CGPathContainsPoint()
может быть полезна в вашем случае.
Также будьте осторожны, если вы получите точку жестов из супервизора, координата может оказаться неправильной с вашим тестом. У вас есть метод конвертации точки из или в систему координат конкретного вида:
- (CGPoint)convertPoint:(CGPoint)point toView:(UIView *)view
- (CGPoint)convertPoint:(CGPoint)point fromView:(UIView *)view
Вы можете создать копию SecurityStampValidator :
public static class MySecurityStampValidator
{
private const string DefaultSecurityStampClaimType = "AspNet.Identity.SecurityStamp";
public static Func<CookieValidateIdentityContext, Task> OnValidateIdentity<TManager, TUser>(
TimeSpan validateInterval, Func<TManager, TUser, Task<ClaimsIdentity>> regenerateIdentity)
where TManager : UserManager<TUser, string>
where TUser : class, IUser<string>
{
return OnValidateIdentity(validateInterval, regenerateIdentity, id => id.GetUserId());
}
public static Func<CookieValidateIdentityContext, Task> OnValidateIdentity<TManager, TUser, TKey>(
TimeSpan validateInterval, Func<TManager, TUser, Task<ClaimsIdentity>> regenerateIdentityCallback,
Func<ClaimsIdentity, TKey> getUserIdCallback)
where TManager : UserManager<TUser, TKey>
where TUser : class, IUser<TKey>
where TKey : IEquatable<TKey>
{
if (getUserIdCallback == null)
{
throw new ArgumentNullException("getUserIdCallback");
}
return async context =>
{
var currentUtc = DateTimeOffset.UtcNow;
if (context.Options != null && context.Options.SystemClock != null)
{
currentUtc = context.Options.SystemClock.UtcNow;
}
var issuedUtc = context.Properties.IssuedUtc;
// Only validate if enough time has elapsed
var validate = (issuedUtc == null);
if (issuedUtc != null)
{
var timeElapsed = currentUtc.Subtract(issuedUtc.Value);
validate = timeElapsed > validateInterval;
}
if (validate)
{
var manager = context.OwinContext.GetUserManager<TManager>();
var userId = getUserIdCallback(context.Identity);
if (manager != null && userId != null)
{
var user = await manager.FindByIdAsync(userId).WithCurrentCulture();
var reject = true;
// Refresh the identity if the stamp matches, otherwise reject
if (user != null && manager.SupportsUserSecurityStamp)
{
var securityStamp =
context.Identity.FindFirstValue(DefaultSecurityStampClaimType);
if (securityStamp == await manager.GetSecurityStampAsync(userId).WithCurrentCulture())
{
reject = false;
// Regenerate fresh claims if possible and resign in
if (regenerateIdentityCallback != null)
{
var identity = await regenerateIdentityCallback.Invoke(manager, user).WithCurrentCulture();
if (identity != null)
{
// Fix for regression where this value is not updated
// Setting it to null so that it is refreshed by the cookie middleware
context.Properties.IssuedUtc = null;
context.Properties.ExpiresUtc = null;
context.OwinContext.Authentication.SignIn(context.Properties, identity);
}
}
}
}
if (reject)
{
// do what you need
var ctx = context.OwinContext.Get<YourDbContext>();
var loggedSession = ctx.LoginSessions.FirstOrDefault(y => y.UserId == 55 && y.SessionId == Session.SessionID);
loggedSession.LoggedIn = false;
ctx.SaveChanges();
context.RejectIdentity();
context.OwinContext.Authentication.SignOut(context.Options.AuthenticationType);
}
}
}
};
}
}
Не забудьте скопировать удостоверение ASPNET TaskExtensions [ 1110] class, потому что это необходимо для сохранения культуры в потоках:
internal static class TaskExtensions
{
public static CultureAwaiter<T> WithCurrentCulture<T>(this Task<T> task)
{
return new CultureAwaiter<T>(task);
}
public static CultureAwaiter WithCurrentCulture(this Task task)
{
return new CultureAwaiter(task);
}
public struct CultureAwaiter<T> : ICriticalNotifyCompletion
{
private readonly Task<T> _task;
public CultureAwaiter(Task<T> task)
{
_task = task;
}
public CultureAwaiter<T> GetAwaiter()
{
return this;
}
public bool IsCompleted
{
get { return _task.IsCompleted; }
}
public T GetResult()
{
return _task.GetAwaiter().GetResult();
}
public void OnCompleted(Action continuation)
{
// The compiler will never call this method
throw new NotImplementedException();
}
public void UnsafeOnCompleted(Action continuation)
{
var currentCulture = Thread.CurrentThread.CurrentCulture;
var currentUiCulture = Thread.CurrentThread.CurrentUICulture;
_task.ConfigureAwait(false).GetAwaiter().UnsafeOnCompleted(() =>
{
var originalCulture = Thread.CurrentThread.CurrentCulture;
var originalUiCulture = Thread.CurrentThread.CurrentUICulture;
Thread.CurrentThread.CurrentCulture = currentCulture;
Thread.CurrentThread.CurrentUICulture = currentUiCulture;
try
{
continuation();
}
finally
{
Thread.CurrentThread.CurrentCulture = originalCulture;
Thread.CurrentThread.CurrentUICulture = originalUiCulture;
}
});
}
}
public struct CultureAwaiter : ICriticalNotifyCompletion
{
private readonly Task _task;
public CultureAwaiter(Task task)
{
_task = task;
}
public CultureAwaiter GetAwaiter()
{
return this;
}
public bool IsCompleted
{
get { return _task.IsCompleted; }
}
public void GetResult()
{
_task.GetAwaiter().GetResult();
}
public void OnCompleted(Action continuation)
{
// The compiler will never call this method
throw new NotImplementedException();
}
public void UnsafeOnCompleted(Action continuation)
{
var currentCulture = Thread.CurrentThread.CurrentCulture;
var currentUiCulture = Thread.CurrentThread.CurrentUICulture;
_task.ConfigureAwait(false).GetAwaiter().UnsafeOnCompleted(() =>
{
var originalCulture = Thread.CurrentThread.CurrentCulture;
var originalUiCulture = Thread.CurrentThread.CurrentUICulture;
Thread.CurrentThread.CurrentCulture = currentCulture;
Thread.CurrentThread.CurrentUICulture = currentUiCulture;
try
{
continuation();
}
finally
{
Thread.CurrentThread.CurrentCulture = originalCulture;
Thread.CurrentThread.CurrentUICulture = originalUiCulture;
}
});
}
}
}
Назначьте валидатор SecurityStamp:
Provider = new CookieAuthenticationProvider
{
OnValidateIdentity = MySecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
validateInterval: TimeSpan.FromHours(8),
regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
}
И все готово.