public override byte[] Handle(string path, Stream request, OSHttpRequest httpRequest, OSHttpResponse httpResponse) { HttpRequestInfo requestInfo = OpenAuthHelper.GetRequestInfo(httpRequest); try { UserAuthorizationRequest oauthRequest = CableBeachServerState.OAuthServiceProvider.ReadAuthorizationRequest(requestInfo); if (oauthRequest != null && oauthRequest.ExtraData != null) { IServiceProviderRequestToken requestToken = CableBeachServerState.OAuthTokenManager.GetRequestToken(oauthRequest.RequestToken); if (requestToken.Callback != null) oauthRequest.Callback = requestToken.Callback; if (oauthRequest.Callback != null) { string capNameList; if (oauthRequest.ExtraData.TryGetValue("cb_capabilities", out capNameList)) { // Store the OAuth request state in a temporary dictionary to reference later string[] capNames = capNameList.Split(','); OAuthRequest thisRequest = new OAuthRequest(null, oauthRequest, capNames); CableBeachServerState.OAuthCurrentRequests.AddOrUpdate(oauthRequest.RequestToken, thisRequest, TimeSpan.FromMinutes(CableBeachServerState.OAUTH_OPENID_LOGIN_TIMEOUT_MINUTES)); HttpCookie cookie = (httpRequest.Cookies != null) ? httpRequest.Cookies["cb_auth"] : null; AuthCookie authCookie; if (cookie != null && CableBeachServerState.AuthCookies.TryGetValue(cookie.Value, out authCookie)) { CableBeachServerState.Log.Debug("[CABLE BEACH SERVER]: Found auth cookie for " + authCookie.Identity); thisRequest.Identity = authCookie.Identity; // Return either a permission grant request page or a successful OAuth authorization response return CableBeachServerState.MakeCheckPermissionsResponse(httpRequest, httpResponse, thisRequest); } #region Start OpenID Auth try { // Redirect the user to do an OpenID login through our trusted identity provider Identifier identifier; Identifier.TryParse(CableBeachServerState.OpenIDProviderUrl.ToString(), out identifier); Realm realm = new Realm(CableBeachServerState.ServiceUrl); IAuthenticationRequest authRequest = CableBeachServerState.OpenIDRelyingParty.CreateRequest( identifier, realm, new Uri(CableBeachServerState.ServiceUrl, "/oauth/openid_callback")); authRequest.AddCallbackArguments("oauth_request_token", oauthRequest.RequestToken); return OpenAuthHelper.MakeOpenAuthResponse(httpResponse, authRequest.RedirectingResponse); } catch (Exception ex) { CableBeachServerState.Log.Error("[CABLE BEACH SERVER]: OpenID authentication failed: " + ex.Message, ex); httpResponse.StatusCode = (int)HttpStatusCode.InternalServerError; return Encoding.UTF8.GetBytes("OpenID authentication failed: " + ex.Message); } #endregion Start OpenID Auth } else { // No capabilities were requested CableBeachServerState.Log.Error("[CABLE BEACH SERVER]: Got an OAuth request with no capabilities being requested"); httpResponse.StatusCode = (int)HttpStatusCode.BadRequest; return Encoding.UTF8.GetBytes("Unknown capabilities"); } } else { // No callback was given CableBeachServerState.Log.Error("[CABLE BEACH SERVER]: Got an OAuth request with no callback"); httpResponse.StatusCode = (int)HttpStatusCode.BadRequest; return Encoding.UTF8.GetBytes("Missing or invalid OAuth callback"); } } else { CableBeachServerState.Log.Error("[CABLE BEACH SERVER]: authorize_token called with missing or invalid OAuth request"); httpResponse.StatusCode = (int)HttpStatusCode.BadRequest; return Encoding.UTF8.GetBytes("Missing or invalid OAuth request"); } } catch (Exception ex) { CableBeachServerState.Log.Error("[CABLE BEACH SERVER]: authorize_token called with invalid data"); httpResponse.StatusCode = (int)HttpStatusCode.BadRequest; return Encoding.UTF8.GetBytes("Failed to handle OAuth request: " + ex.Message); } }
public static UserAuthorizationResponse MakeOAuthSuccessResponse(string requestToken, OAuthRequest oauthRequest) { // Mark the request token as authorized CableBeachServerState.OAuthTokenManager.AuthorizeRequestToken(requestToken); // Create an authorization response (including a verification code) UserAuthorizationResponse oauthResponse = CableBeachServerState.OAuthServiceProvider.PrepareAuthorizationResponse(oauthRequest.Request); // Update the verification code for this request to the newly created verification code try { CableBeachServerState.OAuthTokenManager.GetRequestToken(requestToken).VerificationCode = oauthResponse.VerificationCode; } catch (KeyNotFoundException) { CableBeachServerState.Log.Warn("[CABLE BEACH SERVER]: Did not recognize request token \"" + requestToken + "\", failed to update verification code"); } return oauthResponse; }
public static byte[] BuildPermissionGrantTemplate(OAuthRequest oauthRequest) { string output = null; Dictionary<string, object> variables = new Dictionary<string, object>(); variables["identity"] = oauthRequest.Identity; variables["callback"] = oauthRequest.Request.Callback; variables["request_token"] = oauthRequest.Request.RequestToken; variables["consumer"] = oauthRequest.Request.Callback.Authority; try { output = WebTemplates.Render(PermissionGrantTemplateFile, variables); } catch (Exception) { } if (output == null) { Log.Error("[CABLE BEACH SERVER]: Failed to render template " + PermissionGrantTemplateFile); output = "Failed to render template " + PermissionGrantTemplateFile; } return Encoding.UTF8.GetBytes(output); }
public static byte[] MakeCheckPermissionsResponse(OSHttpRequest httpRequest, OSHttpResponse httpResponse, OAuthRequest oauthRequest) { // Return an auth cookie to the client and check if the current consumer has already been granted permissions bool permissionGranted = SetAuthCookie(httpRequest, httpResponse, oauthRequest.Identity, oauthRequest.Request.Callback.Authority); if (permissionGranted) { UserAuthorizationResponse oauthResponse = MakeOAuthSuccessResponse(oauthRequest.Request.RequestToken, oauthRequest); Log.Info("[CABLE BEACH SERVER]: OAuth confirmation was cached, redirecting to " + oauthRequest.Request.Callback); return OpenAuthHelper.MakeOpenAuthResponse(httpResponse, OAuthServiceProvider.Channel.PrepareResponse(oauthResponse)); } else { // Ask the user if they want to grant capabilities to the requesting world return BuildPermissionGrantTemplate(oauthRequest); } }