Skip to content
This repository was archived by the owner on Mar 20, 2019. It is now read-only.

Commit bbb0214

Browse files
committed
Changed all ASP.NET async void event handlers to use RegisterAsyncTask, which avoids bugs in ASP.NET.
1 parent 9c7bd4a commit bbb0214

File tree

29 files changed

+985
-806
lines changed

29 files changed

+985
-806
lines changed

projecttemplates/WebFormsRelyingParty/Members/OAuthAuthorize.aspx.cs

Lines changed: 68 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -23,52 +23,80 @@ namespace WebFormsRelyingParty.Members {
2323
public partial class OAuthAuthorize : System.Web.UI.Page {
2424
private EndUserAuthorizationRequest pendingRequest;
2525

26-
protected async void Page_Load(object sender, EventArgs e) {
27-
if (!IsPostBack) {
28-
this.pendingRequest = await OAuthServiceProvider.AuthorizationServer.ReadAuthorizationRequestAsync(new HttpRequestWrapper(Request), Response.ClientDisconnectedToken);
29-
if (this.pendingRequest == null) {
30-
throw new HttpException((int)HttpStatusCode.BadRequest, "Missing authorization request.");
31-
}
26+
protected void Page_Load(object sender, EventArgs e) {
27+
this.RegisterAsyncTask(
28+
new PageAsyncTask(
29+
async ct => {
30+
if (!IsPostBack) {
31+
this.pendingRequest =
32+
await
33+
OAuthServiceProvider.AuthorizationServer.ReadAuthorizationRequestAsync(
34+
new HttpRequestWrapper(Request), Response.ClientDisconnectedToken);
35+
if (this.pendingRequest == null) {
36+
throw new HttpException((int)HttpStatusCode.BadRequest, "Missing authorization request.");
37+
}
3238

33-
this.csrfCheck.Value = Code.SiteUtilities.SetCsrfCookie();
34-
var requestingClient = Database.DataContext.Clients.First(c => c.ClientIdentifier == this.pendingRequest.ClientIdentifier);
35-
this.consumerNameLabel.Text = HttpUtility.HtmlEncode(requestingClient.Name);
36-
this.scopeLabel.Text = HttpUtility.HtmlEncode(OAuthUtilities.JoinScopes(this.pendingRequest.Scope));
39+
this.csrfCheck.Value = Code.SiteUtilities.SetCsrfCookie();
40+
var requestingClient =
41+
Database.DataContext.Clients.First(c => c.ClientIdentifier == this.pendingRequest.ClientIdentifier);
42+
this.consumerNameLabel.Text = HttpUtility.HtmlEncode(requestingClient.Name);
43+
this.scopeLabel.Text = HttpUtility.HtmlEncode(OAuthUtilities.JoinScopes(this.pendingRequest.Scope));
3744

38-
// Consider auto-approving if safe to do so.
39-
if (((OAuthAuthorizationServer)OAuthServiceProvider.AuthorizationServer.AuthorizationServerServices).CanBeAutoApproved(this.pendingRequest)) {
40-
var response = OAuthServiceProvider.AuthorizationServer.PrepareApproveAuthorizationRequest(this.pendingRequest, HttpContext.Current.User.Identity.Name);
41-
var responseMessage = await OAuthServiceProvider.AuthorizationServer.Channel.PrepareResponseAsync(response, Response.ClientDisconnectedToken);
42-
await responseMessage.SendAsync(new HttpContextWrapper(this.Context), Response.ClientDisconnectedToken);
43-
this.Context.Response.End();
44-
}
45-
this.ViewState["AuthRequest"] = this.pendingRequest;
46-
} else {
47-
Code.SiteUtilities.VerifyCsrfCookie(this.csrfCheck.Value);
48-
this.pendingRequest = (EndUserAuthorizationRequest)this.ViewState["AuthRequest"];
49-
}
45+
// Consider auto-approving if safe to do so.
46+
if (
47+
((OAuthAuthorizationServer)OAuthServiceProvider.AuthorizationServer.AuthorizationServerServices)
48+
.CanBeAutoApproved(this.pendingRequest)) {
49+
var response = OAuthServiceProvider.AuthorizationServer.PrepareApproveAuthorizationRequest(
50+
this.pendingRequest, HttpContext.Current.User.Identity.Name);
51+
var responseMessage =
52+
await
53+
OAuthServiceProvider.AuthorizationServer.Channel.PrepareResponseAsync(
54+
response, Response.ClientDisconnectedToken);
55+
await responseMessage.SendAsync(new HttpContextWrapper(this.Context), Response.ClientDisconnectedToken);
56+
this.Context.Response.End();
57+
}
58+
this.ViewState["AuthRequest"] = this.pendingRequest;
59+
} else {
60+
Code.SiteUtilities.VerifyCsrfCookie(this.csrfCheck.Value);
61+
this.pendingRequest = (EndUserAuthorizationRequest)this.ViewState["AuthRequest"];
62+
}
63+
}));
5064
}
5165

52-
protected async void yesButton_Click(object sender, EventArgs e) {
53-
var requestingClient = Database.DataContext.Clients.First(c => c.ClientIdentifier == this.pendingRequest.ClientIdentifier);
54-
Database.LoggedInUser.ClientAuthorizations.Add(
55-
new ClientAuthorization {
56-
Client = requestingClient,
57-
Scope = OAuthUtilities.JoinScopes(this.pendingRequest.Scope),
58-
User = Database.LoggedInUser,
59-
CreatedOnUtc = DateTime.UtcNow.CutToSecond(),
60-
});
61-
var response = OAuthServiceProvider.AuthorizationServer.PrepareApproveAuthorizationRequest(this.pendingRequest, HttpContext.Current.User.Identity.Name);
62-
var responseMessage = await OAuthServiceProvider.AuthorizationServer.Channel.PrepareResponseAsync(response, Response.ClientDisconnectedToken);
63-
await responseMessage.SendAsync(new HttpContextWrapper(this.Context), Response.ClientDisconnectedToken);
64-
this.Context.Response.End();
66+
protected void yesButton_Click(object sender, EventArgs e) {
67+
this.RegisterAsyncTask(
68+
new PageAsyncTask(
69+
async ct => {
70+
var requestingClient =
71+
Database.DataContext.Clients.First(c => c.ClientIdentifier == this.pendingRequest.ClientIdentifier);
72+
Database.LoggedInUser.ClientAuthorizations.Add(
73+
new ClientAuthorization {
74+
Client = requestingClient,
75+
Scope = OAuthUtilities.JoinScopes(this.pendingRequest.Scope),
76+
User = Database.LoggedInUser,
77+
CreatedOnUtc = DateTime.UtcNow.CutToSecond(),
78+
});
79+
var response = OAuthServiceProvider.AuthorizationServer.PrepareApproveAuthorizationRequest(
80+
this.pendingRequest, HttpContext.Current.User.Identity.Name);
81+
var responseMessage =
82+
await
83+
OAuthServiceProvider.AuthorizationServer.Channel.PrepareResponseAsync(response, Response.ClientDisconnectedToken);
84+
await responseMessage.SendAsync(new HttpContextWrapper(this.Context), Response.ClientDisconnectedToken);
85+
this.Context.Response.End();
86+
}));
6587
}
6688

67-
protected async void noButton_Click(object sender, EventArgs e) {
68-
var response = OAuthServiceProvider.AuthorizationServer.PrepareRejectAuthorizationRequest(this.pendingRequest);
69-
var responseMessage = await OAuthServiceProvider.AuthorizationServer.Channel.PrepareResponseAsync(response, Response.ClientDisconnectedToken);
70-
await responseMessage.SendAsync(new HttpContextWrapper(this.Context), Response.ClientDisconnectedToken);
71-
this.Context.Response.End();
89+
protected void noButton_Click(object sender, EventArgs e) {
90+
this.RegisterAsyncTask(
91+
new PageAsyncTask(
92+
async ct => {
93+
var response = OAuthServiceProvider.AuthorizationServer.PrepareRejectAuthorizationRequest(this.pendingRequest);
94+
var responseMessage =
95+
await
96+
OAuthServiceProvider.AuthorizationServer.Channel.PrepareResponseAsync(response, Response.ClientDisconnectedToken);
97+
await responseMessage.SendAsync(new HttpContextWrapper(this.Context), Response.ClientDisconnectedToken);
98+
this.Context.Response.End();
99+
}));
72100
}
73101
}
74102
}

samples/OAuthClient/Facebook.aspx.cs

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
using System.Configuration;
44
using System.Net;
55
using System.Web;
6+
using System.Web.UI;
7+
68
using DotNetOpenAuth.ApplicationBlock;
79
using DotNetOpenAuth.ApplicationBlock.Facebook;
810
using DotNetOpenAuth.Messaging;
@@ -14,22 +16,30 @@ public partial class Facebook : System.Web.UI.Page {
1416
ClientCredentialApplicator = ClientCredentialApplicator.PostParameter(ConfigurationManager.AppSettings["facebookAppSecret"]),
1517
};
1618

17-
protected async void Page_Load(object sender, EventArgs e) {
18-
IAuthorizationState authorization = await client.ProcessUserAuthorizationAsync(new HttpRequestWrapper(Request), Response.ClientDisconnectedToken);
19-
if (authorization == null) {
20-
// Kick off authorization request
21-
var request = await client.PrepareRequestUserAuthorizationAsync(cancellationToken: Response.ClientDisconnectedToken);
22-
await request.SendAsync(new HttpContextWrapper(Context), Response.ClientDisconnectedToken);
23-
this.Context.Response.End();
24-
} else {
25-
var request = WebRequest.Create("https://graph.facebook.com/me?access_token=" + Uri.EscapeDataString(authorization.AccessToken));
26-
using (var response = request.GetResponse()) {
27-
using (var responseStream = response.GetResponseStream()) {
28-
var graph = FacebookGraph.Deserialize(responseStream);
29-
this.nameLabel.Text = HttpUtility.HtmlEncode(graph.Name);
30-
}
31-
}
32-
}
19+
protected void Page_Load(object sender, EventArgs e) {
20+
this.RegisterAsyncTask(
21+
new PageAsyncTask(
22+
async ct => {
23+
IAuthorizationState authorization =
24+
await client.ProcessUserAuthorizationAsync(new HttpRequestWrapper(Request), ct);
25+
if (authorization == null) {
26+
// Kick off authorization request
27+
var request =
28+
await client.PrepareRequestUserAuthorizationAsync(cancellationToken: ct);
29+
await request.SendAsync(new HttpContextWrapper(Context), ct);
30+
this.Context.Response.End();
31+
} else {
32+
var request =
33+
WebRequest.Create(
34+
"https://graph.facebook.com/me?access_token=" + Uri.EscapeDataString(authorization.AccessToken));
35+
using (var response = request.GetResponse()) {
36+
using (var responseStream = response.GetResponseStream()) {
37+
var graph = FacebookGraph.Deserialize(responseStream);
38+
this.nameLabel.Text = HttpUtility.HtmlEncode(graph.Name);
39+
}
40+
}
41+
}
42+
}));
3343
}
3444
}
3545
}

samples/OAuthClient/SampleWcf2.aspx.cs

Lines changed: 81 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -50,72 +50,95 @@ private static IAuthorizationState Authorization {
5050
set { HttpContext.Current.Session["Authorization"] = value; }
5151
}
5252

53-
protected async void Page_Load(object sender, EventArgs e) {
54-
if (!IsPostBack) {
55-
// Check to see if we're receiving a end user authorization response.
56-
var authorization = await Client.ProcessUserAuthorizationAsync(new HttpRequestWrapper(Request), Response.ClientDisconnectedToken);
57-
if (authorization != null) {
58-
// We are receiving an authorization response. Store it and associate it with this user.
59-
Authorization = authorization;
60-
Response.Redirect(Request.Path); // get rid of the /?code= parameter
61-
}
62-
}
63-
64-
if (Authorization != null) {
65-
// Indicate to the user that we have already obtained authorization on some of these.
66-
foreach (var li in this.scopeList.Items.OfType<ListItem>().Where(li => Authorization.Scope.Contains(li.Value))) {
67-
li.Selected = true;
68-
}
69-
this.authorizationLabel.Text = "Authorization received!";
70-
if (Authorization.AccessTokenExpirationUtc.HasValue) {
71-
TimeSpan timeLeft = Authorization.AccessTokenExpirationUtc.Value - DateTime.UtcNow;
72-
this.authorizationLabel.Text += string.Format(CultureInfo.CurrentCulture, " (access token expires in {0} minutes)", Math.Round(timeLeft.TotalMinutes, 1));
73-
}
74-
}
75-
76-
this.getNameButton.Enabled = this.getAgeButton.Enabled = this.getFavoriteSites.Enabled = Authorization != null;
53+
protected void Page_Load(object sender, EventArgs e) {
54+
this.RegisterAsyncTask(
55+
new PageAsyncTask(
56+
async ct => {
57+
if (!IsPostBack) {
58+
// Check to see if we're receiving a end user authorization response.
59+
var authorization =
60+
await Client.ProcessUserAuthorizationAsync(new HttpRequestWrapper(Request), Response.ClientDisconnectedToken);
61+
if (authorization != null) {
62+
// We are receiving an authorization response. Store it and associate it with this user.
63+
Authorization = authorization;
64+
Response.Redirect(Request.Path); // get rid of the /?code= parameter
65+
}
66+
}
67+
68+
if (Authorization != null) {
69+
// Indicate to the user that we have already obtained authorization on some of these.
70+
foreach (var li in this.scopeList.Items.OfType<ListItem>().Where(li => Authorization.Scope.Contains(li.Value))) {
71+
li.Selected = true;
72+
}
73+
this.authorizationLabel.Text = "Authorization received!";
74+
if (Authorization.AccessTokenExpirationUtc.HasValue) {
75+
TimeSpan timeLeft = Authorization.AccessTokenExpirationUtc.Value - DateTime.UtcNow;
76+
this.authorizationLabel.Text += string.Format(
77+
CultureInfo.CurrentCulture, " (access token expires in {0} minutes)", Math.Round(timeLeft.TotalMinutes, 1));
78+
}
79+
}
80+
81+
this.getNameButton.Enabled = this.getAgeButton.Enabled = this.getFavoriteSites.Enabled = Authorization != null;
82+
}));
7783
}
7884

79-
protected async void getAuthorizationButton_Click(object sender, EventArgs e) {
80-
string[] scopes = (from item in this.scopeList.Items.OfType<ListItem>()
81-
where item.Selected
82-
select item.Value).ToArray();
83-
84-
var request = await Client.PrepareRequestUserAuthorizationAsync(scopes, cancellationToken: Response.ClientDisconnectedToken);
85-
await request.SendAsync();
86-
this.Context.Response.End();
85+
protected void getAuthorizationButton_Click(object sender, EventArgs e) {
86+
this.RegisterAsyncTask(
87+
new PageAsyncTask(
88+
async ct => {
89+
string[] scopes =
90+
(from item in this.scopeList.Items.OfType<ListItem>() where item.Selected select item.Value).ToArray();
91+
92+
var request =
93+
await Client.PrepareRequestUserAuthorizationAsync(scopes, cancellationToken: Response.ClientDisconnectedToken);
94+
await request.SendAsync();
95+
this.Context.Response.End();
96+
}));
8797
}
8898

89-
protected async void getNameButton_Click(object sender, EventArgs e) {
90-
try {
91-
this.nameLabel.Text = await this.CallServiceAsync(client => client.GetName(), Response.ClientDisconnectedToken);
92-
} catch (SecurityAccessDeniedException) {
93-
this.nameLabel.Text = "Access denied!";
94-
} catch (MessageSecurityException) {
95-
this.nameLabel.Text = "Access denied!";
96-
}
99+
protected void getNameButton_Click(object sender, EventArgs e) {
100+
this.RegisterAsyncTask(
101+
new PageAsyncTask(
102+
async ct => {
103+
try {
104+
this.nameLabel.Text = await this.CallServiceAsync(client => client.GetName(), Response.ClientDisconnectedToken);
105+
} catch (SecurityAccessDeniedException) {
106+
this.nameLabel.Text = "Access denied!";
107+
} catch (MessageSecurityException) {
108+
this.nameLabel.Text = "Access denied!";
109+
}
110+
}));
97111
}
98112

99-
protected async void getAgeButton_Click(object sender, EventArgs e) {
100-
try {
101-
int? age = await this.CallServiceAsync(client => client.GetAge(), Response.ClientDisconnectedToken);
102-
this.ageLabel.Text = age.HasValue ? age.Value.ToString(CultureInfo.CurrentCulture) : "not available";
103-
} catch (SecurityAccessDeniedException) {
104-
this.ageLabel.Text = "Access denied!";
105-
} catch (MessageSecurityException) {
106-
this.ageLabel.Text = "Access denied!";
107-
}
113+
protected void getAgeButton_Click(object sender, EventArgs e) {
114+
this.RegisterAsyncTask(
115+
new PageAsyncTask(
116+
async ct => {
117+
try {
118+
int? age = await this.CallServiceAsync(client => client.GetAge(), Response.ClientDisconnectedToken);
119+
this.ageLabel.Text = age.HasValue ? age.Value.ToString(CultureInfo.CurrentCulture) : "not available";
120+
} catch (SecurityAccessDeniedException) {
121+
this.ageLabel.Text = "Access denied!";
122+
} catch (MessageSecurityException) {
123+
this.ageLabel.Text = "Access denied!";
124+
}
125+
}));
108126
}
109127

110-
protected async void getFavoriteSites_Click(object sender, EventArgs e) {
111-
try {
112-
string[] favoriteSites = await this.CallServiceAsync(client => client.GetFavoriteSites(), Response.ClientDisconnectedToken);
113-
this.favoriteSitesLabel.Text = string.Join(", ", favoriteSites);
114-
} catch (SecurityAccessDeniedException) {
115-
this.favoriteSitesLabel.Text = "Access denied!";
116-
} catch (MessageSecurityException) {
117-
this.favoriteSitesLabel.Text = "Access denied!";
118-
}
128+
protected void getFavoriteSites_Click(object sender, EventArgs e) {
129+
this.RegisterAsyncTask(
130+
new PageAsyncTask(
131+
async ct => {
132+
try {
133+
string[] favoriteSites =
134+
await this.CallServiceAsync(client => client.GetFavoriteSites(), Response.ClientDisconnectedToken);
135+
this.favoriteSitesLabel.Text = string.Join(", ", favoriteSites);
136+
} catch (SecurityAccessDeniedException) {
137+
this.favoriteSitesLabel.Text = "Access denied!";
138+
} catch (MessageSecurityException) {
139+
this.favoriteSitesLabel.Text = "Access denied!";
140+
}
141+
}));
119142
}
120143

121144
private async Task<T> CallServiceAsync<T>(Func<DataApiClient, T> predicate, CancellationToken cancellationToken) {

samples/OAuthClient/WindowsLive.aspx.cs

Lines changed: 32 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -18,31 +18,39 @@ public partial class WindowsLive : System.Web.UI.Page {
1818
ClientCredentialApplicator = ClientCredentialApplicator.PostParameter(ConfigurationManager.AppSettings["WindowsLiveAppSecret"]),
1919
};
2020

21-
protected async void Page_Load(object sender, EventArgs e) {
22-
if (string.Equals("localhost", this.Request.Headers["Host"].Split(':')[0], StringComparison.OrdinalIgnoreCase)) {
23-
this.localhostDoesNotWorkPanel.Visible = true;
24-
var builder = new UriBuilder(this.publicLink.NavigateUrl);
25-
builder.Port = this.Request.Url.Port;
26-
this.publicLink.NavigateUrl = builder.Uri.AbsoluteUri;
27-
this.publicLink.Text = builder.Uri.AbsoluteUri;
28-
} else {
29-
IAuthorizationState authorization = await client.ProcessUserAuthorizationAsync(new HttpRequestWrapper(Request), Response.ClientDisconnectedToken);
30-
if (authorization == null) {
31-
// Kick off authorization request
32-
var request = await client.PrepareRequestUserAuthorizationAsync(scopes: new[] { WindowsLiveClient.Scopes.Basic }); // this scope isn't even required just to log in
33-
await request.SendAsync(new HttpContextWrapper(this.Context), Response.ClientDisconnectedToken);
34-
this.Context.Response.End();
35-
} else {
36-
var request =
37-
WebRequest.Create("https://apis.live.net/v5.0/me?access_token=" + Uri.EscapeDataString(authorization.AccessToken));
38-
using (var response = request.GetResponse()) {
39-
using (var responseStream = response.GetResponseStream()) {
40-
var graph = WindowsLiveGraph.Deserialize(responseStream);
41-
this.nameLabel.Text = HttpUtility.HtmlEncode(graph.Name);
21+
protected void Page_Load(object sender, EventArgs e) {
22+
this.RegisterAsyncTask(
23+
new PageAsyncTask(
24+
async ct => {
25+
if (string.Equals("localhost", this.Request.Headers["Host"].Split(':')[0], StringComparison.OrdinalIgnoreCase)) {
26+
this.localhostDoesNotWorkPanel.Visible = true;
27+
var builder = new UriBuilder(this.publicLink.NavigateUrl);
28+
builder.Port = this.Request.Url.Port;
29+
this.publicLink.NavigateUrl = builder.Uri.AbsoluteUri;
30+
this.publicLink.Text = builder.Uri.AbsoluteUri;
31+
} else {
32+
IAuthorizationState authorization =
33+
await client.ProcessUserAuthorizationAsync(new HttpRequestWrapper(Request), Response.ClientDisconnectedToken);
34+
if (authorization == null) {
35+
// Kick off authorization request
36+
var request =
37+
await client.PrepareRequestUserAuthorizationAsync(scopes: new[] { WindowsLiveClient.Scopes.Basic });
38+
// this scope isn't even required just to log in
39+
await request.SendAsync(new HttpContextWrapper(this.Context), Response.ClientDisconnectedToken);
40+
this.Context.Response.End();
41+
} else {
42+
var request =
43+
WebRequest.Create(
44+
"https://apis.live.net/v5.0/me?access_token=" + Uri.EscapeDataString(authorization.AccessToken));
45+
using (var response = request.GetResponse()) {
46+
using (var responseStream = response.GetResponseStream()) {
47+
var graph = WindowsLiveGraph.Deserialize(responseStream);
48+
this.nameLabel.Text = HttpUtility.HtmlEncode(graph.Name);
49+
}
50+
}
51+
}
4252
}
43-
}
44-
}
45-
}
53+
}));
4654
}
4755
}
4856
}

0 commit comments

Comments
 (0)