diff options
8 files changed, 52 insertions, 32 deletions
diff --git a/projecttemplates/MvcRelyingParty/Controllers/AccountController.cs b/projecttemplates/MvcRelyingParty/Controllers/AccountController.cs index 864a38e..6bd65df 100644 --- a/projecttemplates/MvcRelyingParty/Controllers/AccountController.cs +++ b/projecttemplates/MvcRelyingParty/Controllers/AccountController.cs @@ -48,32 +48,36 @@ return PartialView("EditFields", GetAccountInfoModel()); } - [Authorize] + [Authorize, AcceptVerbs(HttpVerbs.Get | HttpVerbs.Post)] public ActionResult Authorize() { var pendingRequest = OAuthServiceProvider.AuthorizationServer.ReadAuthorizationRequest(); if (pendingRequest == null) { - return RedirectToAction("Edit"); + throw new HttpException((int)HttpStatusCode.BadRequest, "Missing authorization request."); } var requestingClient = Database.DataContext.Clients.First(c => c.ClientIdentifier == pendingRequest.ClientIdentifier); // Consider auto-approving if safe to do so. if (((OAuthAuthorizationServer)OAuthServiceProvider.AuthorizationServer.AuthorizationServer).CanBeAutoApproved(pendingRequest)) { - OAuthServiceProvider.AuthorizationServer.ApproveAuthorizationRequest(pendingRequest, HttpContext.User.Identity.Name); + var approval = OAuthServiceProvider.AuthorizationServer.PrepareApproveAuthorizationRequest(pendingRequest, HttpContext.User.Identity.Name); + return OAuthServiceProvider.AuthorizationServer.Channel.PrepareResponse(approval).AsActionResult(); } var model = new AccountAuthorizeModel { ClientApp = requestingClient.Name, Scope = pendingRequest.Scope, + AuthorizationRequest = pendingRequest, }; return View(model); } [Authorize, AcceptVerbs(HttpVerbs.Post), ValidateAntiForgeryToken] - public ActionResult Authorize(bool isApproved) { - var getRequest = new HttpRequestInfo("GET", this.Request.Url, this.Request.RawUrl, new WebHeaderCollection(), null); - var pendingRequest = OAuthServiceProvider.AuthorizationServer.ReadAuthorizationRequest(getRequest); + public ActionResult AuthorizeResponse(bool isApproved) { + var pendingRequest = OAuthServiceProvider.AuthorizationServer.ReadAuthorizationRequest(); + if (pendingRequest == null) { + throw new HttpException((int)HttpStatusCode.BadRequest, "Missing authorization request."); + } var requestingClient = Database.DataContext.Clients.First(c => c.ClientIdentifier == pendingRequest.ClientIdentifier); IDirectedProtocolMessage response; diff --git a/projecttemplates/MvcRelyingParty/Models/AccountAuthorizeModel.cs b/projecttemplates/MvcRelyingParty/Models/AccountAuthorizeModel.cs index 97c96f0..686d481 100644 --- a/projecttemplates/MvcRelyingParty/Models/AccountAuthorizeModel.cs +++ b/projecttemplates/MvcRelyingParty/Models/AccountAuthorizeModel.cs @@ -4,9 +4,13 @@ using System.Linq; using System.Web; + using DotNetOpenAuth.OAuth2.Messages; + public class AccountAuthorizeModel { public string ClientApp { get; set; } public HashSet<string> Scope { get; set; } + + public EndUserAuthorizationRequest AuthorizationRequest { get; set; } } } diff --git a/projecttemplates/MvcRelyingParty/Views/Account/Authorize.aspx b/projecttemplates/MvcRelyingParty/Views/Account/Authorize.aspx index da2676e..986a3eb 100644 --- a/projecttemplates/MvcRelyingParty/Views/Account/Authorize.aspx +++ b/projecttemplates/MvcRelyingParty/Views/Account/Authorize.aspx @@ -1,4 +1,5 @@ <%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<MvcRelyingParty.Models.AccountAuthorizeModel>" %> +<%@ Import Namespace="DotNetOpenAuth.OAuth2" %> <asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server"> Authorize @@ -24,9 +25,14 @@ If you grant access now, you can revoke it at any time by returning to <%= Html.ActionLink("your account page", "Edit") %>. </p> - <% using (Html.BeginForm()) { %> + <% using (Html.BeginForm("AuthorizeResponse", "Account")) { %> <%= Html.AntiForgeryToken() %> <%= Html.Hidden("IsApproved") %> + <%= Html.Hidden("client_id", Model.AuthorizationRequest.ClientIdentifier) %> + <%= Html.Hidden("redirect_uri", Model.AuthorizationRequest.Callback) %> + <%= Html.Hidden("state", Model.AuthorizationRequest.ClientState) %> + <%= Html.Hidden("scope", OAuthUtilities.JoinScopes(Model.AuthorizationRequest.Scope)) %> + <%= Html.Hidden("response_type", "code") %> <div style="display: none" id="responseButtonsDiv"> <input type="submit" value="Yes" onclick="document.getElementsByName('IsApproved')[0].value = true; return true;" /> <input type="submit" value="No" onclick="document.getElementsByName('IsApproved')[0].value = false; return true;" /> diff --git a/projecttemplates/RelyingPartyLogic/OAuthAuthorizationServer.cs b/projecttemplates/RelyingPartyLogic/OAuthAuthorizationServer.cs index 91a2ac3..8d0bdce 100644 --- a/projecttemplates/RelyingPartyLogic/OAuthAuthorizationServer.cs +++ b/projecttemplates/RelyingPartyLogic/OAuthAuthorizationServer.cs @@ -34,7 +34,13 @@ namespace RelyingPartyLogic { secret = new byte[16]; crypto.GetBytes(secret); - AsymmetricKey = new RSACryptoServiceProvider().ExportParameters(true); + // As we generate a new random key, we need to set the UseMachineKeyStore flag so that this doesn't + // crash on IIS. For more information: + // http://social.msdn.microsoft.com/Forums/en-US/clr/thread/7ea48fd0-8d6b-43ed-b272-1a0249ae490f?prof=required + var cspParameters = new CspParameters(); + cspParameters.Flags = CspProviderFlags.UseArchivableKey | CspProviderFlags.UseMachineKeyStore; + var cryptoProvider = new RSACryptoServiceProvider(cspParameters); + AsymmetricKey = cryptoProvider.ExportParameters(true); } /// <summary> diff --git a/projecttemplates/WebFormsRelyingParty/Members/OAuthAuthorize.aspx.cs b/projecttemplates/WebFormsRelyingParty/Members/OAuthAuthorize.aspx.cs index 05a5f52..8b33696 100644 --- a/projecttemplates/WebFormsRelyingParty/Members/OAuthAuthorize.aspx.cs +++ b/projecttemplates/WebFormsRelyingParty/Members/OAuthAuthorize.aspx.cs @@ -24,17 +24,12 @@ namespace WebFormsRelyingParty.Members { private EndUserAuthorizationRequest pendingRequest; protected void Page_Load(object sender, EventArgs e) { - // We'll mask that on postback it's a POST when looking up the authorization details so that the GET-only - // message can be picked up. - var requestInfo = this.IsPostBack - ? new HttpRequestInfo("GET", this.Request.Url, this.Request.RawUrl, new WebHeaderCollection(), null) - : null; - this.pendingRequest = OAuthServiceProvider.AuthorizationServer.ReadAuthorizationRequest(requestInfo); - if (this.pendingRequest == null) { - Response.Redirect("AccountInfo.aspx"); - } - if (!IsPostBack) { + this.pendingRequest = OAuthServiceProvider.AuthorizationServer.ReadAuthorizationRequest(); + if (this.pendingRequest == null) { + throw new HttpException((int)HttpStatusCode.BadRequest, "Missing authorization request."); + } + this.csrfCheck.Value = Code.SiteUtilities.SetCsrfCookie(); var requestingClient = Database.DataContext.Clients.First(c => c.ClientIdentifier == this.pendingRequest.ClientIdentifier); this.consumerNameLabel.Text = HttpUtility.HtmlEncode(requestingClient.Name); @@ -44,8 +39,10 @@ namespace WebFormsRelyingParty.Members { if (((OAuthAuthorizationServer)OAuthServiceProvider.AuthorizationServer.AuthorizationServer).CanBeAutoApproved(this.pendingRequest)) { OAuthServiceProvider.AuthorizationServer.ApproveAuthorizationRequest(this.pendingRequest, HttpContext.Current.User.Identity.Name); } + this.ViewState["AuthRequest"] = this.pendingRequest; } else { Code.SiteUtilities.VerifyCsrfCookie(this.csrfCheck.Value); + this.pendingRequest = (EndUserAuthorizationRequest)this.ViewState["AuthRequest"]; } } diff --git a/samples/OAuthConsumerWpf/Authorize2.xaml.cs b/samples/OAuthConsumerWpf/Authorize2.xaml.cs index 8cf9f6f..86d8d9e 100644 --- a/samples/OAuthConsumerWpf/Authorize2.xaml.cs +++ b/samples/OAuthConsumerWpf/Authorize2.xaml.cs @@ -41,11 +41,11 @@ } private void locationChanged(Uri location) { - if (location.Scheme == "res") { - this.DialogResult = false; - this.Close(); - MessageBox.Show("An error occurred during authorization."); - } + //if (location.Scheme == "res") { + // this.DialogResult = false; + // this.Close(); + // MessageBox.Show("An error occurred during authorization."); + //} if (SignificantlyEqual(location, this.Authorization.Callback, UriComponents.SchemeAndServer | UriComponents.Path)) { try { diff --git a/samples/OAuthConsumerWpf/MainWindow.xaml.cs b/samples/OAuthConsumerWpf/MainWindow.xaml.cs index e62683d..b194777 100644 --- a/samples/OAuthConsumerWpf/MainWindow.xaml.cs +++ b/samples/OAuthConsumerWpf/MainWindow.xaml.cs @@ -233,8 +233,10 @@ MessageBox.Show(this, ex.Message); } catch (WebException ex) { string responseText = string.Empty; - using (var responseReader = new StreamReader(ex.Response.GetResponseStream())) { - responseText = responseReader.ReadToEnd(); + if (ex.Response != null) { + using (var responseReader = new StreamReader(ex.Response.GetResponseStream())) { + responseText = responseReader.ReadToEnd(); + } } MessageBox.Show(this, ex.Message + " " + responseText); } diff --git a/src/DotNetOpenAuth/OAuth2/AuthorizationServer.cs b/src/DotNetOpenAuth/OAuth2/AuthorizationServer.cs index 37be337..5f251e1 100644 --- a/src/DotNetOpenAuth/OAuth2/AuthorizationServer.cs +++ b/src/DotNetOpenAuth/OAuth2/AuthorizationServer.cs @@ -48,12 +48,7 @@ namespace DotNetOpenAuth.OAuth2 { public void ApproveAuthorizationRequest(EndUserAuthorizationRequest authorizationRequest, string username, IEnumerable<string> scopes = null, Uri callback = null) { Contract.Requires<ArgumentNullException>(authorizationRequest != null, "authorizationRequest"); - var response = this.PrepareApproveAuthorizationRequest(authorizationRequest, username, callback); - - // Customize the approved scope if the authorization server has decided to do so. - if (scopes != null) { - response.Scope.ResetContents(scopes); - } + var response = this.PrepareApproveAuthorizationRequest(authorizationRequest, username, scopes, callback); this.Channel.Send(response); } @@ -107,7 +102,7 @@ namespace DotNetOpenAuth.OAuth2 { return response; } - public EndUserAuthorizationSuccessResponseBase PrepareApproveAuthorizationRequest(EndUserAuthorizationRequest authorizationRequest, string username, Uri callback = null) { + public EndUserAuthorizationSuccessResponseBase PrepareApproveAuthorizationRequest(EndUserAuthorizationRequest authorizationRequest, string username, IEnumerable<string> scopes = null, Uri callback = null) { Contract.Requires<ArgumentNullException>(authorizationRequest != null, "authorizationRequest"); Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(username)); Contract.Ensures(Contract.Result<EndUserAuthorizationSuccessResponseBase>() != null); @@ -131,6 +126,12 @@ namespace DotNetOpenAuth.OAuth2 { } response.AuthorizingUsername = username; + + // Customize the approved scope if the authorization server has decided to do so. + if (scopes != null) { + response.Scope.ResetContents(scopes); + } + return response; } |