WebAPI 的绝对和空闲会话超时
Absolute and idle session timeout owin WebAPI
我正在创建一个使用 OAuth Bearer 身份验证的 WebAPI,如下所示:
var oAuthServerOptions = new OAuthAuthorizationServerOptions
{
TokenEndpointPath = new PathString("/token"),
AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(100),
Provider = new AuthorizationServerProvider(),
RefreshTokenProvider = new RefreshTokenProvider(),
};
应用程序将为经过身份验证的用户生成令牌,该令牌将在 100 分钟后过期。用户必须使用刷新令牌才能继续访问应用程序。
现在,我想更改政策如下:
- 如果用户空闲 100 分钟,则用户必须重新登录(应用程序必须 return 401)- 空闲超时
- 如果用户不空闲则事件,用户必须在 8 小时后再次登录 - 绝对超时
我已经搜索了好几天了,但是找不到合适的解决方案
这里有解决我的问题的解决方案或示例吗?
目前,我删除了刷新令牌功能,因此用户必须在 100 分钟后再次登录。
非常感谢。
我看不到在 OAuth 2.0 中同时设置两个超时的方法。
仅针对第一次超时,idle超时,可以将refresh token timeout设置为100分钟。访问令牌超时时间会更短,每次访问令牌过期时,您都会获得新的访问令牌和刷新令牌。如果用户会话空闲时间超过 100 分钟,当应用尝试刷新令牌时,oauth 服务器将意识到刷新令牌已过期且无效。然后用户将需要输入他们的凭据。
对于第二次超时,您可以将访问令牌超时设置为 8 小时,并且不实现刷新令牌。
考虑到令牌将被发送到资源服务器,它不能与 oauth 服务器相同。资源服务器只能检查令牌中的票证是否过期,但无法控制用户输入凭据后第一次授予令牌的时间。
如果您同时控制 oauth 和资源服务器,则可以采取变通方法,为刷新令牌实施 100 分钟超时,并在票证中包含 属性 以及用户输入凭据的时间。请参阅下面的代码作为示例:
public class AuthorizationServerProvider : OAuthAuthorizationServerProvider
{
...
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
...
var props = new AuthenticationProperties(new Dictionary<string, string>
{
{
"client_id", clientId
},
{
"ownerCredentialsTimestamp", DateTime.UtcNow.ToString()
}
});
var ticket = new AuthenticationTicket(identity, props);
context.Validated(ticket);
}
...
}
资源服务器获取token中包含的ticket时,可以将属性中的值与当前时间进行比较。如果差异大于 8 小时,可以 return 401 - 未经授权的响应,强制客户端应用程序请求另一个访问令牌:
public class AccessTokenProvider : IAuthenticationTokenProvider
{
public async Task ReceiveAsync(AuthenticationTokenReceiveContext context)
{
context.DeserializeTicket(context.Token);
if (context.Ticket.Properties.Dictionary["ownerCredentialsTimestamp"] != null)
{
var ownerCredentialsTimestamp = Convert.ToDateTime(context.Ticket.Properties.Dictionary["ownerCredentialsTimestamp"]).ToUniversalTime();
if (/* difference is bigger than 8 hours */)
{
context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
}
}
}
}
此时,客户端应用程序将尝试通过 "refresh_token" 请求获取新的访问令牌。 oauth 服务器必须再次检查与当前刷新令牌相关的最后输入凭据的时间,数据库 table 中可能有一列存储刷新令牌(如果是这种情况)。
您可以在RefreshTokenProvider.ReceiveAsync()
方法中检查它:
public class RefreshTokenProvider : IAuthenticationTokenProvider
{
...
public async Task ReceiveAsync(AuthenticationTokenReceiveContext context)
{
...
/* Check the received refresh token, including the last time that the credentials were entered for this user */
...
}
...
}
或在AuthorizationServerProvicer.GrantRefreshToken()
方法中:
public class AuthorizationServerProvider : OAuthAuthorizationServerProvider
{
...
public override async Task GrantRefreshToken(OAuthGrantRefreshTokenContext context)
{
...
/* Check the last time that the credentials were entered for this user */
...
}
...
}
这是一个非常特殊的解决方案,与 OAuth 2.0 协议无关。
希望对你有所帮助
我正在创建一个使用 OAuth Bearer 身份验证的 WebAPI,如下所示:
var oAuthServerOptions = new OAuthAuthorizationServerOptions
{
TokenEndpointPath = new PathString("/token"),
AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(100),
Provider = new AuthorizationServerProvider(),
RefreshTokenProvider = new RefreshTokenProvider(),
};
应用程序将为经过身份验证的用户生成令牌,该令牌将在 100 分钟后过期。用户必须使用刷新令牌才能继续访问应用程序。 现在,我想更改政策如下:
- 如果用户空闲 100 分钟,则用户必须重新登录(应用程序必须 return 401)- 空闲超时
- 如果用户不空闲则事件,用户必须在 8 小时后再次登录 - 绝对超时
我已经搜索了好几天了,但是找不到合适的解决方案
这里有解决我的问题的解决方案或示例吗? 目前,我删除了刷新令牌功能,因此用户必须在 100 分钟后再次登录。
非常感谢。
我看不到在 OAuth 2.0 中同时设置两个超时的方法。
仅针对第一次超时,idle超时,可以将refresh token timeout设置为100分钟。访问令牌超时时间会更短,每次访问令牌过期时,您都会获得新的访问令牌和刷新令牌。如果用户会话空闲时间超过 100 分钟,当应用尝试刷新令牌时,oauth 服务器将意识到刷新令牌已过期且无效。然后用户将需要输入他们的凭据。
对于第二次超时,您可以将访问令牌超时设置为 8 小时,并且不实现刷新令牌。
考虑到令牌将被发送到资源服务器,它不能与 oauth 服务器相同。资源服务器只能检查令牌中的票证是否过期,但无法控制用户输入凭据后第一次授予令牌的时间。
如果您同时控制 oauth 和资源服务器,则可以采取变通方法,为刷新令牌实施 100 分钟超时,并在票证中包含 属性 以及用户输入凭据的时间。请参阅下面的代码作为示例:
public class AuthorizationServerProvider : OAuthAuthorizationServerProvider
{
...
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
...
var props = new AuthenticationProperties(new Dictionary<string, string>
{
{
"client_id", clientId
},
{
"ownerCredentialsTimestamp", DateTime.UtcNow.ToString()
}
});
var ticket = new AuthenticationTicket(identity, props);
context.Validated(ticket);
}
...
}
资源服务器获取token中包含的ticket时,可以将属性中的值与当前时间进行比较。如果差异大于 8 小时,可以 return 401 - 未经授权的响应,强制客户端应用程序请求另一个访问令牌:
public class AccessTokenProvider : IAuthenticationTokenProvider
{
public async Task ReceiveAsync(AuthenticationTokenReceiveContext context)
{
context.DeserializeTicket(context.Token);
if (context.Ticket.Properties.Dictionary["ownerCredentialsTimestamp"] != null)
{
var ownerCredentialsTimestamp = Convert.ToDateTime(context.Ticket.Properties.Dictionary["ownerCredentialsTimestamp"]).ToUniversalTime();
if (/* difference is bigger than 8 hours */)
{
context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
}
}
}
}
此时,客户端应用程序将尝试通过 "refresh_token" 请求获取新的访问令牌。 oauth 服务器必须再次检查与当前刷新令牌相关的最后输入凭据的时间,数据库 table 中可能有一列存储刷新令牌(如果是这种情况)。
您可以在RefreshTokenProvider.ReceiveAsync()
方法中检查它:
public class RefreshTokenProvider : IAuthenticationTokenProvider
{
...
public async Task ReceiveAsync(AuthenticationTokenReceiveContext context)
{
...
/* Check the received refresh token, including the last time that the credentials were entered for this user */
...
}
...
}
或在AuthorizationServerProvicer.GrantRefreshToken()
方法中:
public class AuthorizationServerProvider : OAuthAuthorizationServerProvider
{
...
public override async Task GrantRefreshToken(OAuthGrantRefreshTokenContext context)
{
...
/* Check the last time that the credentials were entered for this user */
...
}
...
}
这是一个非常特殊的解决方案,与 OAuth 2.0 协议无关。
希望对你有所帮助