/// <summary> /// RPC endpoint for clients to actually authenticate after requesting authentication and /// computing a signature from the authentication challenge. /// </summary> /// <seealso cref="M:WampSharp.Cra.IWampCraProcedures.Auth(string)"/> public WampCraPermissions Auth(string signature) { ValidateAuthState(); CheckSignature(signature); // At this point, the client has successfully authenticated! // Get the permissions we determined earlier WampCraPermissions perms = mPendingAuth.Permissions; // Delete auth request and mark client as authenticated string authKey = mPendingAuth.AuthInfo.authkey; mAuthenticated = true; mPendingAuth = null; // TODO: If implementing a pending auth timeout, here is where you would cancel it // TODO: (_clientAuthTimeoutCall in autobahn python) RaiseOnAuthenticated(authKey, perms); // Return permissions to client mPermissions.AddPermissions(perms); return(perms); }
private void CheckSignature(string signature) { // Check signature if (!string.Equals(mPendingAuth.Signature, signature, StringComparison.Ordinal)) { // Delete pending authentication, so that no retries are possible. authid is only valid for 1 try!! mPendingAuth = null; // Notify the client of failed authentication, but only after a random, // exponentially distributed delay. this (further) protects against // timing attacks Random random = new Random(); double randNum = random.Next(1, 101) / 100.0d; double failDelaySecs = Math.Log(1.0d - randNum) / ((1.0d / 0.8d) * -1.0d); //mean = 0.8 secs Thread.Sleep(Convert.ToInt32(failDelaySecs * 1000.0d)); ThrowHelper.InvalidSignature(); } }
/// <summary> /// RPC endpoint for clients to initiate the authentication handshake. /// </summary> /// <seealso cref="M:WampSharp.Cra.IWampCraProcedures.AuthReq(string,IDictionary{string,string})"/> public string AuthReq(string authKey, IDictionary <string, string> extra) { ValidateAuthReqStatus(authKey); string authSecret = GetAuthReqSecret(authKey); // each authentication request gets a unique authid, which can only be used (later) once! string authid = mIdGenerator.Generate(); //check extra if (extra == null) { extra = new Dictionary <string, string>(); } Dictionary <string, string> extraAuth = new Dictionary <string, string>(extra); WampCraPermissions permissions = GetAuthReqPermissions(authKey, extraAuth); WampCraChallenge info = new WampCraChallenge(authid, authKey, DateTime.UtcNow, mClientSessionId, extra, permissions, extraAuth); mAuthKey = authKey; if (string.IsNullOrEmpty(authKey)) { // anonymous session mPendingAuth = new WampCraPendingAuth(info, null, permissions); return(null); } // authenticated session string infoser = mFormatter.Serialize(info).ToString(); string sig = WampCraHelpers.AuthSignature(infoser, authSecret, info.authextra); mPendingAuth = new WampCraPendingAuth(info, sig, permissions); return(infoser); }