====== Digest Authentication Sequence ====== Different parties can request you to authenticate yourself - prove your identity. Using digest authentication you prove your identity by knowing your password. For security reasons the password itself is not transmitted on wire, only an MD5 hash sum. If you have specified a SIP address as [[ixnx:wrtc:js:api:wrtc:addressname|wrtc.addressName]] the SIP registrar of that domain most probably will request you to authenticate yourself already in the [[ixnx:wrtc:js:start_sequence#wrtc.event.authenticate|start sequence]] once your webpage has been loaded. But you might be required to authenticate yourself at any other time too. Most of the authentication sequence is automatically taken care by wrtc_kit, usually you do not need to write any code. Just make sure you have entered valid values into: | [[ixnx:wrtc:js:api:wrtc:sipauthname|wrtc.sipAuthName]] | user's SIP authentication (login) name | | [[ixnx:wrtc:js:api:wrtc:sipha1|wrtc.sipHa1]] | hash sum of the user's [[ixnx:wrtc:js:api:wrtc:sippassword|SIP password]] (generated by wrtc_kit) | | [[ixnx:wrtc:js:api:wrtc:sippassword|wrtc.sipPassword]] | user's SIP password | Basic implementations will automatically respond to //all// digest authentication requests using the login and password contained in those properties. It will work fine in most cases. More advanced implementations may however define their own [[ixnx:wrtc:js:api:wrtc:onauthenticate|wrtc.onAuthenticate()]] function and use different login and password for different realm domains. **When someone requests digest authentication from you the following happens:** ===== wrtc.onAuthenticate() ===== [[ixnx:wrtc:js:api:wrtc:onauthenticate|wrtc.onAuthenticate()]] occurs when someone has requested you to authenticate yourself. **You do not need however to write any wrtc.onAuthenticate() function**, except in advanced scenarios, see chapter Multiple Realms below. If you have not defined your own [[ixnx:wrtc:js:api:wrtc:onauthenticate|wrtc.onAuthenticate()]] function wrtc_kit will just call [[ixnx:wrtc:js:api:line:authenticate|line.authenticate()]] without any arguments making it use wrtc object properties [[ixnx:wrtc:js:api:wrtc:sipauthname|sipAuthName]], [[ixnx:wrtc:js:api:wrtc:sippassword|sipPassword]] or [[ixnx:wrtc:js:api:wrtc:sipha1|sipHa1]] and attempt to authenticate you using them. ===== wrtc.onAuthenticateFailed() ===== If the server has not accepted your authentication event [[ixnx:wrtc:js:api:wrtc:onauthenticatefailed|wrtc.onAuthenticateFailed()]] will occur, immediately followed by a [[ixnx:wrtc:js:api:wrtc:onloggedout|wrtc.onLoggedOut()]]. You should write your own wrtc.onAuthenticateFailed() function and alert user of the login failure and perhaps ask for new password. There is no reason to retry the authentication with the old credentials. ===== wrtc.onLoggedIn() ===== If the server has accepted your authentication event [[ixnx:wrtc:js:api:wrtc:onloggedin|wrtc.onLoggedIn()]] will occur. You should write your own [[ixnx:wrtc:js:api:wrtc:onloggedin|wrtc.onLoggedIn()]] function and notify user she has been logged in. ====== Password vs Ha1 ====== Saving the user's authentication password in clear text in a cookie is a major security issue. To avoid it wrtc_kit supplies you with [[ixnx:wrtc:js:api:wrtc:sipha1|wrtc.sipHa1]] that is a hash sum of the [[ixnx:wrtc:js:api:wrtc:sippassword|wrtc.sipPassword]] password. The first time user enters her password you store it in [[ixnx:wrtc:js:api:wrtc:sippassword|wrtc.sipPassword]]. Then you may call [[ixnx:wrtc:js:api:wrtc:changecredentials|wrtc.changeCredentials()]] to manually trigger a new authentication. If you have //not// defined any [[ixnx:wrtc:js:api:wrtc:onauthenticate|wrtc.onAuthenticate()]] function then: ===== ===== During authentication [[ixnx:wrtc:js:api:line:authenticate|line.authenticate()]] is called automatically, it calculates a hash sum of the password and stores it in [[ixnx:wrtc:js:api:wrtc:sipha1|wrtc.sipHa1]]. That hash sum is all it needs for future authentications, you no longer need the password in clear text. [[ixnx:wrtc:js:api:line:authenticate|line.authenticate()]] therefore sets [[ixnx:wrtc:js:api:wrtc:sippassword|wrtc.sipPassword]] to undefined again. Next time [[ixnx:wrtc:js:api:line:authenticate|line.authenticate()]] is called it will detect [[ixnx:wrtc:js:api:wrtc:sippassword|wrtc.sipPassword]] is undefined but [[ixnx:wrtc:js:api:wrtc:sipha1|sipHa1]] is present and use that value instead. If you store user's password in a cookie you should store [[ixnx:wrtc:js:api:wrtc:sipha1|wrtc.sipHa1]], preferably in [[ixnx:wrtc:js:api:wrtc:onloggedin|wrtc.onLoggedIn()]]. Next time page is loaded you can read back the value from the cookie to [[ixnx:wrtc:js:api:wrtc:sipha1|wrtc.sipHa1]] preferably in [[ixnx:wrtc:js:api:wrtc:init|wrtc.init()]] and then the hash sum will be used for authentication and no trace of the password in clear text remains anywhere. Thus [[ixnx:wrtc:js:api:wrtc:sippassword|wrtc.sipPassword]] is a //temporary// storage of the password in clear text, until first call of [[ixnx:wrtc:js:api:line:authenticate|line.authenticate()]] and [[ixnx:wrtc:js:api:wrtc:sipha1|sipHa1]] has been calculated. ====== ====== If you //have// defined your own [[ixnx:wrtc:js:api:wrtc:onauthenticate|wrtc.onAuthenticate()]] function then: ===== ===== After you have called [[ixnx:wrtc:js:api:line:authenticate|line.authenticate()]] with {sipAuthName:…, sipPassword:…} as argument and it has returned true the sipHa1 will be added to the argument: wrtc.onAuthenticate = function(line, realm) { var credentials = {}; credentials.sipAuthName = -- username entered by user --; if ( -- you have a stored HA1 hash sum for this realm -- ) { credentials.sipHa1 = -- the stored HA1 hash sum --; line.authenticate(credentials); } else { credentials.sipPassword = -- password entered by user --; if (line.authenticate(credentials) == true) -- credentials.sipHa1 now contains the calculated HA1 hash sum and can be stored for later -- } } ====== Tips and tricks ====== ===== Multiple Realms ===== If you have not defined your own [[ixnx:wrtc:js:api:wrtc:onauthenticate|wrtc.onAuthenticate()]] function wrtc_kit will always use wrtc object properties [[ixnx:wrtc:js:api:wrtc:sipauthname|sipAuthName]], [[ixnx:wrtc:js:api:wrtc:sippassword|sipPassword]] or [[ixnx:wrtc:js:api:wrtc:sipha1|sipHa1]] when attempting to authenticate you. Thus the same login and password will be used to all servers requesting digest authentication. To implement support of different authentication for different requesting servers you should define your own [[ixnx:wrtc:js:api:wrtc:onauthenticate|wrtc.onAuthenticate()]] function, examine its realm argument and call [[ixnx:wrtc:js:api:line:authenticate|line.authenticate()]] with different arguments depending on what server has requested the authentication. ===== Trigger new authentication ===== To manually trigger a new authentication, eg when user has changed her password, you can call [[ixnx:wrtc:js:api:wrtc:changecredentials|wrtc.changeCredentials()]]. It triggers reauthentication on all your connections. To manually trigger a new authentication only on one connection call [[ixnx:wrtc:js:api:line:reportname|line.reportName()]]. You only need to call [[ixnx:wrtc:js:api:wrtc:changecredentials|wrtc.changeCredentials()]] if something has changed with user identity settings. Normal reauthentication after timeout is carried out by wrtc_kit automatically.