使用IRequiresSessionState, IReadOnlySessionState打破oauth2,但需要设置
本文关键字:设置 打破 IRequiresSessionState IReadOnlySessionState 使用 oauth2 | 更新日期: 2023-09-27 18:08:01
我有一个用c#编写的通用处理程序-这被称为OAuth2过程的一部分,通过Google验证用户。
一旦确定了正确的用户,我需要设置一个cookie,以便网站的其他部分可以识别该用户。
问题是为了设置会话变量的处理程序需要实现IRequiresSessionState -当我这样做-然后OAuth 2进程失败与以下错误。
收到的回调和客户端状态不匹配的OAuth授权响应异常
所以我可以实现OAuth或写一个会话变量,但不能两者都做。我可以让OAuth调用第一个页面,但随后可以在URL中看到代码(我宁愿不这样做-因为它为任何邪恶的人提供了破坏安全性的线索)。我可以得到一个页面调用处理程序,返回JSON来识别用户,并有页面本身设置会话变量,然后转到第一页-但这个页面将没有内容,以及需要两个跳转-所以你怎么能有一个HTML页面,本质上是空的,或者设置会话没有IRequiresSessionState打破会话。
OAuth处理程序的代码如下:
public void ProcessRequest(HttpContext context)
{
NetworkParameters networkParameters = null;
NetworkParameter networkParameter = null;
WebServerClient consumer = null;
AuthorizationServerDescription server = null;
IAuthorizationState grantedAccess = null;
LoginResult loginResult = null;
String code = String.Empty;
String result = String.Empty;
String consumerSecret = String.Empty;
String consumerKey = String.Empty;
String securityCookieVal = String.Empty;
Uri tokenEndpoint = null;
Uri authorizationEndpoint = null;
Profile profile = null;
Profile profile2 = null;
Profiles profiles = null;
NetworkAuthorizations authorizations = null;
NetworkAuthorization na = null;
try
{
loginResult = new LoginResult();
tokenEndpoint = new Uri("https://accounts.google.com/o/oauth2/token");
authorizationEndpoint = new Uri("https://accounts.google.com/o/oauth2/auth?access_type=offline&approval_prompt=auto");
// retrieve network parameters
networkParameters = new NetworkParameters(Properties.Settings.Default.DatabaseConnection);
authorizations = new NetworkAuthorizations(Properties.Settings.Default.DatabaseConnection);
networkParameter = networkParameters.Select("GOOGLE");
code = context.Request["code"];
consumerKey = networkParameter.ClientId;
consumerSecret = networkParameter.ClientSecret;
// set up request
server = new AuthorizationServerDescription();
server.AuthorizationEndpoint = authorizationEndpoint;
server.TokenEndpoint = tokenEndpoint;
server.ProtocolVersion = ProtocolVersion.V20;
// initialise webserver client
consumer = new WebServerClient(server, consumerKey, consumerSecret);
consumer.ClientCredentialApplicator = ClientCredentialApplicator.PostParameter(consumerSecret);
// retrieve access
grantedAccess = consumer.ProcessUserAuthorization();
profile = GoogleServices.GetProfile(grantedAccess.AccessToken);
profiles = new Profiles(Properties.Settings.Default.DatabaseConnection);
profile2 = profiles.SelectByNetworkId(profile.Network, profile.NetworkId);
if (profile2 == null)
{
na = new NetworkAuthorization()
{
Id = Guid.NewGuid().ToString(),
AccessToken = grantedAccess.AccessToken,
ExpirationDate = (DateTime)grantedAccess.AccessTokenExpirationUtc,
IssueDate = (DateTime)grantedAccess.AccessTokenIssueDateUtc,
RefreshToken = grantedAccess.RefreshToken,
Network = profile.Network,
NetworkId = profile.NetworkId
};
authorizations.Insert(na);
profiles.Insert(profile);
}
loginResult.UserId = profile.NetworkId;
}
catch (System.Exception e)
{
loginResult.Status.Status = "ERROR";
loginResult.Status.Message = e.Message;
}
finally
{
context.Response.ContentType = "application/json";
context.Response.Write(JsonConvert.SerializeObject(loginResult));
}
}
不是真正的答案-但我通过将随机生成的id传递给网站的第一页来解决这个问题,并将其存储在用户- cookie在第一页被调用时设置。
在查询字符串中发送这样的信息并不安全,但在原型中就足够了-最终的计划是使用Node.js,这将不会是一个问题。