Example #1
0
        private CookieAuthenticationEvents get_sams_authentication_events()
        {
            //https://stackoverflow.com/questions/52175302/handling-expired-refresh-tokens-in-asp-net-core

            var sams_endpoint_authorization    = Configuration["sams:endpoint_authorization"];
            var sams_endpoint_token            = Configuration["sams:endpoint_token"];
            var sams_endpoint_user_info        = Configuration["sams:endpoint_user_info"];
            var sams_endpoint_token_validation = Configuration["sams:token_validation"];
            var sams_endpoint_user_info_sys    = Configuration["sams:user_info_sys"];
            var sams_client_id     = Configuration["sams:client_id"];
            var sams_client_secret = Configuration["sams:client_secret"];
            var sams_callback_url  = Configuration["sams:callback_url"];

            var result = new CookieAuthenticationEvents
            {
                OnValidatePrincipal = context =>
                {
                    //check to see if user is authenticated first
                    if (context.Principal.Identity.IsAuthenticated)
                    {
                        var expires_at = context.Request.Cookies["expires_at"];

                        var expires_at_time = DateTimeOffset.Parse(expires_at);

/*
 *                      var accessToken = context.Request.HttpContext.Session.GetString("access_token");
 *                      var refreshToken = context.Request.HttpContext.Session.GetString("refresh_token");
 *                      var exp = context.Request.HttpContext.Session.GetInt32("expires_in");
 */

                        /*
                         *          var tokens = context.Properties.GetTokens();
                         *          var refreshToken = tokens.FirstOrDefault(t => t.Name == "refresh_token");
                         *          var accessToken = tokens.FirstOrDefault(t => t.Name == "access_token");
                         *          var exp = tokens.FirstOrDefault(t => t.Name == "expires_at");
                         *          var expires = DateTime.Parse(exp.Value);
                         */

                        //context.Request.Cookies.["sid"].
                        // var expires = DateTime.Parse(exp.ToString());
                        //check to see if the token has expired
                        if (expires_at_time.DateTime < DateTime.Now)
                        {
                            try
                            {
                                var sid = context.Request.Cookies["sid"];

                                string request_string = Program.config_couchdb_url + $"/session/{sid}";
                                var    curl           = new cURL("GET", null, request_string, null, Program.config_timer_user_name, Program.config_timer_password);
                                string session_json   = curl.execute();
                                var    session        = Newtonsoft.Json.JsonConvert.DeserializeObject <mmria.common.model.couchdb.session> (session_json);

                                var userName = context.Principal.Identities.First(
                                    u => u.IsAuthenticated &&
                                    u.HasClaim(c => c.Type == ClaimTypes.Name)).FindFirst(ClaimTypes.Name).Value;


                                if (!userName.Equals(session.user_id, StringComparison.OrdinalIgnoreCase))
                                {
                                    context.RejectPrincipal();
                                    return(Task.CompletedTask);
                                }

                                var accessToken  = session.data["access_token"];
                                var refreshToken = session.data["refresh_token"];
                                var exp          = session.data["expires_at"];
                                expires_at_time = DateTimeOffset.Parse(exp);

                                // server-side check for expiration
                                if (expires_at_time.DateTime < DateTime.Now)
                                {
                                    //token is expired, let's attempt to renew
                                    var tokenEndpoint = sams_endpoint_token;
                                    var tokenClient   = new mmria.server.util.TokenClient(Configuration);

                                    //var name = HttpContext.Session.GetString(SessionKeyName);
                                    //var name = HttpContext.Session.GetString(SessionKeyName);

                                    var tokenResponse = tokenClient.get_refresh_token(accessToken.ToString(), refreshToken.ToString()).Result;
                                    //check for error while renewing - any error will trigger a new login.
                                    if (tokenResponse.is_error)
                                    {
                                        //reject Principal
                                        context.RejectPrincipal();
                                        return(Task.CompletedTask);
                                    }
                                    //set new token values
                                    refreshToken = tokenResponse.refresh_token;
                                    accessToken  = tokenResponse.access_token;
                                    var unix_time = DateTimeOffset.UtcNow.AddSeconds(tokenResponse.expires_in);

                                    session.data["access_token"]  = accessToken;
                                    session.data["refresh_token"] = refreshToken;
                                    session.data["expires_at"]    = unix_time.ToString();

                                    context.Response.Cookies.Append("expires_at", unix_time.ToString());


                                    session.date_last_updated = DateTime.UtcNow;


                                    var Session_Message = new mmria.server.model.actor.Session_Message
                                                          (
                                        session._id,               //_id =
                                        session._rev,              //_rev =
                                        session.date_created,      //date_created =
                                        session.date_last_updated, //date_last_updated =
                                        session.date_expired,      //date_expired =

                                        session.is_active,         //is_active =
                                        session.user_id,           //user_id =
                                        session.ip,                //ip =
                                        session.session_event_id,  // session_event_id =
                                        session.data
                                                          );

                                    Program.actorSystem.ActorOf(Props.Create <mmria.server.model.actor.Post_Session>()).Tell(Session_Message);

                                    //trigger context to renew cookie with new token values
                                    context.ShouldRenew = true;
                                    return(Task.CompletedTask);
                                }
                            }
                            catch (Exception ex)
                            {
                                // do nothing for now document doesn't exsist.
                                System.Console.WriteLine($"err caseController.Post\n{ex}");
                            }
                        }
                    }
                    return(Task.CompletedTask);
                }
            };

            return(result);
        }
Example #2
0
        public async Task <ActionResult> SignInCallback()
        {
            var sams_endpoint_authorization    = _configuration["sams:endpoint_authorization"];
            var sams_endpoint_token            = _configuration["sams:endpoint_token"];
            var sams_endpoint_user_info        = _configuration["sams:endpoint_user_info"];
            var sams_endpoint_token_validation = _configuration["sams:token_validation"];
            var sams_endpoint_user_info_sys    = _configuration["sams:endpoint_user_info_sys"];
            var sams_client_id     = _configuration["sams:client_id"];
            var sams_client_secret = _configuration["sams:client_secret"];

            var sams_callback_url = _configuration["sams:callback_url"];

            //?code=6c17b2a3-d65a-44fd-a28c-9aee982f80be&state=a4c8326ca5574999aa13ca02e9384c3d
            // Retrieve code and state from query string, pring for debugging
            var querystring       = Request.QueryString.Value;
            var querystring_skip  = querystring.Substring(1, querystring.Length - 1);
            var querystring_array = querystring_skip.Split("&");

            var querystring_dictionary = new Dictionary <string, string>();

            foreach (string item in querystring_array)
            {
                var pair = item.Split("=");
                querystring_dictionary.Add(pair[0], pair[1]);
            }

            var code  = querystring_dictionary["code"];
            var state = querystring_dictionary["state"];

            System.Diagnostics.Debug.WriteLine($"code: {code}");
            System.Diagnostics.Debug.WriteLine($"state: {state}");

            HttpClient client  = new HttpClient();
            var        request = new HttpRequestMessage(HttpMethod.Post, sams_endpoint_token);

            /*
             * request.Content = new FormUrlEncodedContent(new Dictionary<string, string> {
             *  { "client_id", sams_client_id },
             *  { "client_secret", sams_client_secret },
             *  { "grant_type", "client_credentials" },
             *  { "code", code },
             * });
             */

            request.Content = new FormUrlEncodedContent(new Dictionary <string, string> {
                { "client_id", sams_client_id },
                { "client_secret", sams_client_secret },
                { "grant_type", "authorization_code" },
                { "code", code },
                { "scope", "openid profile email" },
                { "redirect_uri", sams_callback_url }
            });


            var response = await client.SendAsync(request);

            response.EnsureSuccessStatusCode();

            var payload       = JObject.Parse(await response.Content.ReadAsStringAsync());
            var access_token  = payload.Value <string>("access_token");
            var refresh_token = payload.Value <string>("refresh_token");
            var expires_in    = payload.Value <int>("expires_in");


            var scope = payload.Value <string>("scope");

            //HttpContext.Session.SetString("access_token", access_token);
            //HttpContext.Session.SetString("refresh_token", refresh_token);

            var unix_time = DateTimeOffset.UtcNow.AddSeconds(expires_in);
            //HttpContext.Session.SetString("expires_at", unix_time.ToString());



            var id_token = payload.Value <string>("id_token");;
            var id_array = id_token.Split('.');


            var replaced_value = id_array[1].Replace('-', '+').Replace('_', '/');
            var base64         = replaced_value.PadRight(replaced_value.Length + (4 - replaced_value.Length % 4) % 4, '=');


            var id_0 = DecodeToken(id_array[0]);
            var id_1 = DecodeToken(id_array[1]);

            var id_body = Base64Decode(base64);

            var user_info_sys_request = new HttpRequestMessage(HttpMethod.Post, sams_endpoint_user_info + "?token=" + id_token);


            user_info_sys_request.Headers.Add("Authorization", "Bearer " + access_token);
            user_info_sys_request.Headers.Add("client_id", sams_client_id);
            user_info_sys_request.Headers.Add("client_secret", sams_client_secret);

            /*
             * user_info_sys_request.Content = new FormUrlEncodedContent(new Dictionary<string, string> {
             *  { "client_id", sams_client_id },
             *  { "client_secret", sams_client_secret },
             *  { "grant_type", "client_credentials" },
             *  { "scope", scope },
             * });
             */



            response = await client.SendAsync(user_info_sys_request);

            response.EnsureSuccessStatusCode();

            var temp_string = await response.Content.ReadAsStringAsync();

            payload = JObject.Parse(temp_string);


            var email = payload.Value <string>("email");


            //check if user exists
            var config_couchdb_url     = _configuration["mmria_settings:couchdb_url"];
            var config_timer_user_name = _configuration["mmria_settings:timer_user_name"];
            var config_timer_password  = _configuration["mmria_settings:timer_password"];

            mmria.common.model.couchdb.user user = null;
            try
            {
                string request_string     = config_couchdb_url + "/_users/" + System.Web.HttpUtility.HtmlEncode("org.couchdb.user:"******"GET", null, request_string, null, config_timer_user_name, config_timer_password);
                var    responseFromServer = await user_curl.executeAsync();

                user = Newtonsoft.Json.JsonConvert.DeserializeObject <mmria.common.model.couchdb.user>(responseFromServer);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }

            mmria.common.model.couchdb.document_put_response user_save_result = null;

            if (user == null)// if user does NOT exists create user with email
            {
                user = add_new_user(email.ToLower(), Guid.NewGuid().ToString());

                try
                {
                    Newtonsoft.Json.JsonSerializerSettings settings = new Newtonsoft.Json.JsonSerializerSettings();
                    settings.NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore;
                    var object_string = Newtonsoft.Json.JsonConvert.SerializeObject(user, settings);

                    string user_db_url = config_couchdb_url + "/_users/" + user._id;

                    var user_curl          = new mmria.server.cURL("PUT", null, user_db_url, object_string, config_timer_user_name, config_timer_password);
                    var responseFromServer = await user_curl.executeAsync();

                    user_save_result = Newtonsoft.Json.JsonConvert.DeserializeObject <mmria.common.model.couchdb.document_put_response>(responseFromServer);
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex);
                }
            }

            //create login session
            if (user_save_result == null || user_save_result.ok)
            {
                var session_data = new System.Collections.Generic.Dictionary <string, string>(StringComparer.InvariantCultureIgnoreCase);
                session_data["access_token"]  = access_token;
                session_data["refresh_token"] = refresh_token;
                session_data["expires_at"]    = unix_time.ToString();

                await create_user_principal(user.name, new List <string>(), unix_time.DateTime);


                var Session_Event_Message = new mmria.server.model.actor.Session_Event_Message
                                            (
                    DateTime.Now,
                    user.name,
                    this.GetRequestIP(),
                    mmria.server.model.actor.Session_Event_Message.Session_Event_Message_Action_Enum.successful_login
                                            );

                _actorSystem.ActorOf(Props.Create <mmria.server.model.actor.Record_Session_Event>()).Tell(Session_Event_Message);



                var Session_Message = new mmria.server.model.actor.Session_Message
                                      (
                    Guid.NewGuid().ToString(), //_id =
                    null,                      //_rev =
                    DateTime.Now,              //date_created =
                    DateTime.Now,              //date_last_updated =
                    null,                      //date_expired =

                    true,                      //is_active =
                    user.name,                 //user_id =
                    this.GetRequestIP(),       //ip =
                    Session_Event_Message._id, // session_event_id =
                    session_data
                                      );

                _actorSystem.ActorOf(Props.Create <mmria.server.model.actor.Post_Session>()).Tell(Session_Message);
                Response.Cookies.Append("sid", Session_Message._id);
                Response.Cookies.Append("expires_at", unix_time.ToString());
                //return RedirectToAction("Index", "HOME");
                //return RedirectToAction("Index", "HOME");
            }

            return(RedirectToAction("Index", "HOME"));

            // Generate JWT for token request
            //var cert = new X509Certificate2(Server.MapPath("~/App_Data/cert.pfx"), "1234");

            /*
             * var cert = new X509Certificate2();
             * var signingCredentials = new SigningCredentials(new X509SecurityKey(cert), SecurityAlgorithms.RsaSha256);
             * var header = new JwtHeader(signingCredentials);
             *
             * var header = new JwtHeader();
             * var payload = new JwtPayload
             * {
             *  {"iss", sams_client_id},
             *  {"sub", sams_client_id},
             *  {"aud", $"{sams_endpoint_token}"},
             *  {"jti", Guid.NewGuid().ToString("N")},
             *  {"exp", (int)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds + 5 * 60}
             * };
             * var securityToken = new JwtSecurityToken(header, payload);
             * var handler = new JwtSecurityTokenHandler();
             * var tokenString = handler.WriteToken(securityToken);
             *
             * // Send POST to make token request
             * using (var wb = new WebClient())
             * {
             *  var data = new NameValueCollection();
             *  data["client_assertion"] = tokenString;
             *  data["client_assertion_type"] = HttpUtility.HtmlEncode("urn:ietf:params:oauth:client-assertion-type:jwt-bearer");
             *  data["code"] = code;
             *  data["grant_type"] = "authorization_code";
             *
             *  //var response = wb.UploadValues($"{IdpUrl}/api/openid_connect/token", "POST", data);
             *  var response = wb.UploadValues($"{sams_endpoint_token}", "POST", data);
             *
             *  var responseString = Encoding.ASCII.GetString(response);
             *  dynamic tokenResponse = JObject.Parse(responseString);
             *
             *  var token = handler.ReadToken((String)tokenResponse.id_token) as JwtSecurityToken;
             *  var userId = token.Claims.First(c => c.Type == "sub").Value;
             *  var userEmail = token.Claims.First(c => c.Type == "email").Value;
             *
             *  TempData["id"] = userId;
             *  TempData["email"] = userEmail;
             *  //return RedirectToAction("Index", "HOME");
             *  return RedirectToAction("Index", "HOME");
             * }*/
        }