/*************** Start defining OAuth flows ************************/ public Task Login_StartAsync(HttpContext httpContext) { var context = new SVAuthRequestContext(SVX_Principal, httpContext); // The SymT doesn't actually get used, but why not. var _AuthorizationRequest = SVX.SVX_Ops.Call(createAuthorizationRequest, context.channel); // NOTE: We are assuming that the target URL used by // marshalAuthorizationRequest belongs to the principal // idpParticipantId.principal. We haven't extended SVX enforcement // that far yet. messageStructures.authorizationRequest.Export(_AuthorizationRequest, context.channel, idpParticipantId.principal); var rawReq = marshalAuthorizationRequest(_AuthorizationRequest); rawReq = attach_concdst_conckey(rawReq, httpContext, "++"); //set the referrer in the CurrentUrl cookie try { Microsoft.Extensions.Primitives.StringValues referer; if (context.http.Request.Headers.TryGetValue("referer", out referer)) { context.http.Response.Headers["set-cookie"] = Microsoft.Extensions.Primitives.StringValues.Concat (context.http.Response.Headers["set-cookie"], "LandingUrl=" + System.Net.WebUtility.UrlDecode(referer) + ";path=/"); } } catch (Exception ex) { //there is already a set-cookie for LandingUrl }; context.http.Response.StatusCode = 303; context.http.Response.Redirect(rawReq); return(Task.CompletedTask); }
JObject detach_concdst_conckey_formpost(ref SVAuthRequestContext context, string delim) { JObject jo = new JObject(context.http.Request.Form.Select(q => new JProperty(q.Key, q.Value.Single()))); string state = jo["state"].ToString(); if (String.IsNullOrEmpty(state)) { throw new Exception("The STATE parameter is missing."); } int pos1 = state.IndexOf(delim); if (pos1 > 1) { int pos2 = state.Substring(pos1 + 2).IndexOf(delim); if (pos2 > 1) { context.concdst = System.Net.WebUtility.UrlDecode(state.Substring(0, pos1)); context.conckey = System.Net.WebUtility.UrlDecode(state.Substring(pos1 + 2, pos2)); var state1 = state.Substring(pos1 + pos2 + 2 + 2); jo["state"] = state1; } } return(jo); }
string detach_concdst_conckey(ref SVAuthRequestContext context, string delim) { string rawReq = System.Net.WebUtility.UrlDecode(context.http.Request.QueryString.Value); int pos0 = rawReq.IndexOf("&state=") + ("&state=".Length); if (pos0 < "&state=".Length) { pos0 = rawReq.IndexOf("?state=") + ("?state=".Length); if (pos0 < "?state=".Length) { throw new Exception("state parameter is missing"); } } int pos1 = rawReq.Substring(pos0).IndexOf(delim); if (pos1 > 1) { int pos2 = rawReq.Substring(pos0 + pos1 + 2).IndexOf(delim); if (pos2 > 1) { context.concdst = System.Net.WebUtility.UrlDecode(rawReq.Substring(pos0, pos1)); context.conckey = System.Net.WebUtility.UrlDecode(rawReq.Substring(pos0 + pos1 + 2, pos2)); var rawReq1 = rawReq.Substring(0, pos0) + rawReq.Substring(pos0 + pos1 + pos2 + 2 + 2); rawReq = rawReq1; } } return(rawReq); }
public override async Task AuthorizationCodeFlow_Login_CallbackAsync(HttpContext httpContext) { var idp = CreateModelOIDCAuthenticationServer(); Trace.Write("AuthorizationCodeFlow_Login_CallbackAsync"); var context = new SVAuthRequestContext(SVX_Principal, httpContext); var dummyAuthorizationRequest = new AuthorizationRequest(); //REDACTED's original implementation, without detaching concdst_conckey /*var authorizationResponse = (OAuth20.AuthorizationResponse)Utils.ObjectFromFormPost( * context.http.Request.Form,typeof(OAuth20.AuthorizationResponse)); */ JObject jo = detach_concdst_conckey_formpost(ref context, " "); AuthorizationResponse authorizationResponse = (AuthorizationResponse)Utils.UnreflectObject(jo, typeof(AuthorizationResponse));; GetMessageStructures().authorizationResponse.ImportWithModel(authorizationResponse, () => { idp.FakeCodeEndpoint(dummyAuthorizationRequest, authorizationResponse); }, SVX.Channel.GenerateNew(SVX_Principal), // unknown producer context.channel); /*GetMessageStructures().authorizationResponse.Import(authenticationResponse, * SVX.PrincipalFacet.GenerateNew(SVX_Principal), // unknown producer * context.client);*/ var _AccessTokenRequest = SVX.SVX_Ops.Call(createAccessTokenRequest, authorizationResponse); GetMessageStructures().accessTokenRequest.Export(_AccessTokenRequest, idpParticipantId.principal, null); var rawReq = marshalAccessTokenRequest(_AccessTokenRequest); var RawAccessTokenResponse = await Utils.PerformHttpRequestAsync(rawReq); Trace.Write("Got AccessTokenResponse"); JObject jObject = JObject.Parse(RawAccessTokenResponse.Content.ReadAsStringAsync().Result); TokenResponse tokenResponse = Utils.UnreflectObject <TokenResponse>(jObject); GetMessageStructures().tokenResponse.ImportDirectResponseWithModel(tokenResponse, () => { idp.FakeTokenEndpoint(_AccessTokenRequest, tokenResponse); }, idpParticipantId.principal, SVX_Principal ); if (!String.IsNullOrEmpty(tokenResponse.id_token.theParams.nonce)) { HashAlgorithm hashAlgo = SHA1.Create(); string expected_nonce = BitConverter.ToString(hashAlgo.ComputeHash(System.Text.Encoding.UTF8.GetBytes(context.channel.id))); if (expected_nonce != tokenResponse.id_token.theParams.nonce) { throw new Exception("invalid nonce"); } } var conclusion = SVX.SVX_Ops.Call(createConclusionOidc, authorizationResponse, tokenResponse); await AuthenticationDone(conclusion, context); }
public Task Login_StartAsync(HttpContext httpContext) { var context = new SVAuthRequestContext(SVX_Principal, httpContext); var _AuthenticationRequest = SVX.SVX_Ops.Call(createAuthenticationRequest, context.channel); // NOTE: We are assuming that the target URL used by // marshalAuthorizationRequest belongs to the principal // idpParticipantId.principal. We haven't extended SVX enforcement // that far yet. GetMessageStructures().authenticationRequest.Export(_AuthenticationRequest, context.channel, idpParticipantId.principal); // Move CSRF_state into return_to. _AuthenticationRequest.openid__return_to += "?CSRF_state=" + Uri.EscapeDataString(_AuthenticationRequest.CSRF_state.Export()); _AuthenticationRequest.CSRF_state = null; //add conckey /* string conckey = httpContext.Request.Query["conckey"]; * if (conckey!=null) * _AuthenticationRequest.openid__return_to += "&conckey=" + Uri.EscapeDataString(conckey);*/ string concdst = httpContext.Request.Query["concdst"]; if (concdst != null) { _AuthenticationRequest.openid__assoc_handle = Uri.EscapeDataString(concdst); } string conckey = httpContext.Request.Query["conckey"]; if (conckey != null) { _AuthenticationRequest.openid__assoc_handle += "++" + Uri.EscapeDataString(conckey); } var rawReq = marshalAuthenticationRequest(_AuthenticationRequest); //set the referrer in the CurrentUrl cookie try { Microsoft.Extensions.Primitives.StringValues referer; if (context.http.Request.Headers.TryGetValue("referer", out referer)) { context.http.Response.Headers["set-cookie"] = Microsoft.Extensions.Primitives.StringValues.Concat (context.http.Response.Headers["set-cookie"], "LandingUrl=" + System.Net.WebUtility.UrlDecode(referer) + ";path=/"); } } catch (Exception ex) { //there is already a set-cookie for LandingUrl }; context.http.Response.StatusCode = 303; context.http.Response.Redirect(rawReq); return(Task.CompletedTask); }
public async Task AuthenticationDone(AuthenticationConclusion conclusion, SVAuthRequestContext context) { if (context.channel != conclusion.channel) { throw new Exception("Attempt to apply an AuthenticationConclusion to the wrong channel."); } if (!BypassCertification) { SVX.SVX_Ops.Certify(conclusion, LoginSafety, idpParticipantId); SVX.SVX_Ops.Certify(conclusion, LoginIntent, idpParticipantId); } await Utils.AbandonAndCreateSessionAsync(conclusion, context); }
public async Task ImplicitFlow_Login_CallbackAsync(HttpContext httpContext) { Trace.Write("ImplicitFlow_Login_CallbackAsync"); var context = new SVAuthRequestContext(SVX_Principal, httpContext); //REDACTED's original implementation, without detaching concdst_conckey /*AuthenticationResponse_with_id_token authenticationResponse_with_id_token= (AuthenticationResponse_with_id_token)Utils.ObjectFromFormPost * (context.http.Request.Form, typeof(AuthenticationResponse_with_id_token)); */ JObject jo = detach_concdst_conckey_formpost(ref context, " "); AuthenticationResponse_with_id_token authenticationResponse_with_id_token = (AuthenticationResponse_with_id_token)Utils.UnreflectObject(jo, typeof(AuthenticationResponse_with_id_token));; var idp = CreateModelOIDCAuthenticationServer(); var dummyAuthorizationRequest = new AuthorizationRequest(); GetMessageStructures().authenticationResponse_with_id_token.ImportWithModel(authenticationResponse_with_id_token, () => { idp.FakeImplicitFlowIDTokenEndpoint(dummyAuthorizationRequest, authenticationResponse_with_id_token); }, SVX.Channel.GenerateNew(SVX_Principal), // unknown producer context.channel); Trace.Write("Got Valid AuthenticationResponse"); if (!String.IsNullOrEmpty(authenticationResponse_with_id_token.id_token.theParams.nonce)) { HashAlgorithm hashAlgo = SHA1.Create(); string expected_nonce = BitConverter.ToString(hashAlgo.ComputeHash(System.Text.Encoding.UTF8.GetBytes(context.channel.id))); if (expected_nonce != authenticationResponse_with_id_token.id_token.theParams.nonce) { throw new Exception("invalid nonce"); } } GenericAuth.AuthenticationConclusion conclusion = SVX_Ops.Call(createConclusionOidcImplicit, authenticationResponse_with_id_token); if (conclusion == null) { context.http.Response.StatusCode = 303; context.http.Response.Redirect(context.http.Request.Cookies["LandingUrl"]); return; } await AuthenticationDone(conclusion, context); }
public async Task Login_CallbackAsync(HttpContext httpContext) { var idp = CreateModelOpenID20AuthenticationServer(); var dummyAuthenticationRequest = new AuthenticationRequest(); Trace.Write("Login_CallbackAsync"); var context = new SVAuthRequestContext(SVX_Principal, httpContext); AuthenticationResponse inputMSG = parse_AuthenticationResponse(context.http); if (inputMSG.openid__ns != "http://specs.openid.net/auth/2.0") { throw new Exception("Openid.ns does not contain the expected value."); } GetMessageStructures().authenticationResponse.ImportWithModel(inputMSG, () => { idp.FakeAuthenticationEndpoint(dummyAuthenticationRequest, inputMSG); }, SVX.Channel.GenerateNew(SVX_Principal), // unknown producer context.channel); Trace.Write("Got Valid AuthenticationResponse"); GenericAuth.AuthenticationConclusion conclusion = SVX_Ops.Call(createConclusion, inputMSG); if (conclusion == null) { context.http.Response.StatusCode = 303; context.http.Response.Redirect(context.http.Request.Cookies["LandingUrl"]); return; } if (Config.config.AgentSettings.agentScope != "local") { string s = inputMSG.FieldsExpectedToBeSigned.theParams.openid__invalidate_handle; int delim = s.IndexOf("++"); if (delim < 7) { throw new Exception("invalid conckey and concdst"); } context.conckey = s.Substring(delim + 2); context.concdst = System.Net.WebUtility.UrlDecode(s.Substring(0, delim)); } await AuthenticationDone(conclusion, context); }
public virtual async Task AuthorizationCodeFlow_Login_CallbackAsync(HttpContext httpContext) { Trace.Write("AuthorizationCodeFlow_Login_CallbackAsync"); var context = new SVAuthRequestContext(SVX_Principal, httpContext); var idp = CreateModelAuthorizationServer(); var rawReq = detach_concdst_conckey(ref context, " "); // See if any subclasses need us to use their special // AuthorizationRequest subclass. var dummyAuthorizationRequest = new AuthorizationRequest(); // This design is following the original Auth.JS as closely as // possible. Arguably, we should give concrete subclasses full // control of unmarshalling, just like marshalling. The original // parseHttpMessage supports both requests (query) and responses, // but here we know which is which. // ~ REDACTED 2016-06-01 // var authorizationResponse = (AuthorizationResponse)Utils.ObjectFromQuery( // context.http.Request.Query, LoginCallbackRequestType); var authorizationResponse = (AuthorizationResponse)Utils.ObjectFromQueryString( rawReq, LoginCallbackRequestType); messageStructures.authorizationResponse.ImportWithModel(authorizationResponse, () => { idp.FakeCodeEndpoint(dummyAuthorizationRequest, authorizationResponse); }, SVX.Channel.GenerateNew(SVX_Principal), // unknown producer context.channel); var accessTokenRequest = SVX.SVX_Ops.Call(createAccessTokenRequest, authorizationResponse); messageStructures.accessTokenRequest.Export(accessTokenRequest, idp.SVX_Principal, null); /*string concdst = httpContext.Request.Query["concdst"]; * if (concdst != null) * accessTokenRequest.redirect_uri += "?concdst=" + Uri.EscapeDataString(concdst); * string conckey = httpContext.Request.Query["conckey"]; * if (conckey != null) * accessTokenRequest.redirect_uri += "&conckey=" + Uri.EscapeDataString(conckey);*/ var rawAccessTokenRequest = marshalAccessTokenRequest(accessTokenRequest); var rawAccessTokenResponse = await Utils.PerformHttpRequestAsync(rawAccessTokenRequest); Trace.Write("Got AccessTokenResponse"); var accessTokenResponse = (AccessTokenResponse)JsonConvert.DeserializeObject( Utils.ReadContent(rawAccessTokenResponse.Content), AccessTokenResponseType); messageStructures.accessTokenResponse.ImportDirectResponseWithModel(accessTokenResponse, () => { idp.FakeTokenEndpoint(accessTokenRequest, accessTokenResponse); }, idp.SVX_Principal, SVX_Principal); var userProfileRequest = SVX.SVX_Ops.Call(createUserProfileRequest, accessTokenResponse); messageStructures.userProfileRequest.Export(userProfileRequest, idp.SVX_Principal, null); var rawUserProfileRequest = marshalUserProfileRequest(userProfileRequest); var rawUserProfileResponse = await Utils.PerformHttpRequestAsync(rawUserProfileRequest); Trace.Write("Got UserProfileResponse"); var userProfileResponse = (UserProfileResponse)JsonConvert.DeserializeObject( Utils.ReadContent(rawUserProfileResponse.Content), UserProfileResponseType); messageStructures.userProfileResponse.ImportDirectResponseWithModel(userProfileResponse, () => { idp.FakeUserProfileEndpoint(userProfileRequest, userProfileResponse); }, idp.SVX_Principal, SVX_Principal); var conclusion = SVX.SVX_Ops.Call(createConclusion, authorizationResponse, userProfileResponse); await AuthenticationDone(conclusion, context); }