/// <summary> /// Activates an existing session /// </summary> public virtual bool ActivateSession( OperationContext context, NodeId authenticationToken, SignatureData clientSignature, List <SoftwareCertificate> clientSoftwareCertificates, ExtensionObject userIdentityToken, SignatureData userTokenSignature, StringCollection localeIds, out byte[] serverNonce) { serverNonce = null; Session session = null; UserIdentityToken newIdentity = null; UserTokenPolicy userTokenPolicy = null; lock (m_lock) { // find session. if (!m_sessions.TryGetValue(authenticationToken, out session)) { throw new ServiceResultException(StatusCodes.BadSessionClosed); } // check if session timeout has expired. if (session.HasExpired) { m_server.CloseSession(null, session.Id, false); throw new ServiceResultException(StatusCodes.BadSessionClosed); } // create new server nonce. serverNonce = Utils.Nonce.CreateNonce((uint)m_minNonceLength); // validate before activation. session.ValidateBeforeActivate( context, clientSignature, clientSoftwareCertificates, userIdentityToken, userTokenSignature, localeIds, serverNonce, out newIdentity, out userTokenPolicy); } IUserIdentity identity = null; IUserIdentity effectiveIdentity = null; ServiceResult error = null; try { // check if the application has a callback which validates the identity tokens. lock (m_eventLock) { if (m_ImpersonateUser != null) { ImpersonateEventArgs args = new ImpersonateEventArgs(newIdentity, userTokenPolicy); m_ImpersonateUser(session, args); if (ServiceResult.IsBad(args.IdentityValidationError)) { error = args.IdentityValidationError; } else { identity = args.Identity; effectiveIdentity = args.EffectiveIdentity; } } } // parse the token manually if the identity is not provided. if (identity == null) { identity = new UserIdentity(newIdentity); } // use the identity as the effectiveIdentity if not provided. if (effectiveIdentity == null) { effectiveIdentity = identity; } } catch (Exception e) { if (e is ServiceResultException) { throw e; } throw ServiceResultException.Create( StatusCodes.BadIdentityTokenInvalid, e, "Could not validate user identity token: {0}", newIdentity); } // check for validation error. if (ServiceResult.IsBad(error)) { throw new ServiceResultException(error); } // activate session. bool contextChanged = session.Activate( context, clientSoftwareCertificates, newIdentity, identity, effectiveIdentity, localeIds, serverNonce); // raise session related event. if (contextChanged) { RaiseSessionEvent(session, SessionEventReason.Activated); } // indicates that the identity context for the session has changed. return(contextChanged); }
/// <summary> /// Called when a client tries to change its user identity. /// </summary> private void SessionManager_ImpersonateUser(Session session, ImpersonateEventArgs args) { // check for a WSS token. IssuedIdentityToken wssToken = args.NewIdentity as IssuedIdentityToken; // check for a user name token. UserNameIdentityToken userNameToken = args.NewIdentity as UserNameIdentityToken; if (userNameToken != null) { VerifyPassword(userNameToken.UserName, userNameToken.DecryptedPassword); args.Identity = new UserIdentity(userNameToken); Utils.Trace("UserName Token Accepted: {0}", args.Identity.DisplayName); return; } // check for x509 user token. X509IdentityToken x509Token = args.NewIdentity as X509IdentityToken; if (userNameToken != null) { VerifyCertificate(x509Token.Certificate); args.Identity = new UserIdentity(x509Token); Utils.Trace("X509 Token Accepted: {0}", args.Identity.DisplayName); return; } }
/// <summary> /// Called when a client tries to change its user identity. /// </summary> private void SessionManager_ImpersonateUser(Session session, ImpersonateEventArgs args) { // check for a user name token. UserNameIdentityToken userNameToken = args.NewIdentity as UserNameIdentityToken; if (userNameToken != null) { VerifyPassword(userNameToken.UserName, userNameToken.DecryptedPassword); args.Identity = new UserIdentity(userNameToken); return; } }
/// <summary> /// Activates an existing session /// </summary> public virtual bool ActivateSession( OperationContext context, NodeId authenticationToken, SignatureData clientSignature, List<SoftwareCertificate> clientSoftwareCertificates, ExtensionObject userIdentityToken, SignatureData userTokenSignature, StringCollection localeIds, out byte[] serverNonce) { serverNonce = null; Session session = null; UserIdentityToken newIdentity = null; UserTokenPolicy userTokenPolicy = null; lock (m_lock) { // find session. if (!m_sessions.TryGetValue(authenticationToken, out session)) { throw new ServiceResultException(StatusCodes.BadSessionClosed); } // create new server nonce. serverNonce = new byte[m_minNonceLength]; IBuffer buffer = CryptographicBuffer.GenerateRandom((uint) m_minNonceLength); CryptographicBuffer.CopyToByteArray(buffer, out serverNonce); // validate before activation. session.ValidateBeforeActivate( context, clientSignature, clientSoftwareCertificates, userIdentityToken, userTokenSignature, localeIds, serverNonce, out newIdentity, out userTokenPolicy); } IUserIdentity identity = null; IUserIdentity effectiveIdentity = null; ServiceResult error = null; try { // check if the application has a callback which validates the identity tokens. lock (m_eventLock) { if (m_ImpersonateUser != null) { ImpersonateEventArgs args = new ImpersonateEventArgs(newIdentity, userTokenPolicy); m_ImpersonateUser(session, args); if (ServiceResult.IsBad(args.IdentityValidationError)) { error = args.IdentityValidationError; } else { identity = args.Identity; effectiveIdentity = args.EffectiveIdentity; } } } // parse the token manually if the identity is not provided. if (identity == null) { identity = new UserIdentity(newIdentity); } // use the identity as the effectiveIdentity if not provided. if (effectiveIdentity == null) { effectiveIdentity = identity; } } catch (Exception e) { if (e is ServiceResultException) { throw; } throw ServiceResultException.Create( StatusCodes.BadIdentityTokenInvalid, e, "Could not validate user identity token: {0}", newIdentity); } // check for validation error. if (ServiceResult.IsBad(error)) { throw new ServiceResultException(error); } // activate session. bool contextChanged = session.Activate( context, clientSoftwareCertificates, newIdentity, identity, effectiveIdentity, localeIds, serverNonce); // raise session related event. if (contextChanged) { RaiseSessionEvent(session, SessionEventReason.Activated); } // indicates that the identity context for the session has changed. return contextChanged; }
/// <summary> /// Called when a client tries to change its user identity. /// </summary> private void SessionManager_ImpersonateUser(Session session, ImpersonateEventArgs args) { // check for a user name token. UserNameIdentityToken userNameToken = args.NewIdentity as UserNameIdentityToken; if (userNameToken != null) { VerifyPassword(userNameToken.UserName, userNameToken.DecryptedPassword); args.Identity = new UserIdentity(userNameToken); Utils.Trace("UserName Token Accepted: {0}", args.Identity.DisplayName); } }
/// <summary> /// Check whether it is an acceptable session. /// </summary> /// <param name="session">The session.</param> /// <param name="args">IdentityToken.</param> void SessionManager_ImpersonateUser(Session session, ImpersonateEventArgs args) { switch (args.UserTokenPolicy.TokenType) { case UserTokenType.UserName: UserNameIdentityToken token = args.NewIdentity as UserNameIdentityToken; if (!m_userNameValidator.Validate(token)) { // Bad user access denied. // construct translation object with default text. TranslationInfo info = new TranslationInfo( "InvalidUserInformation", "en-US", "Specified user information are not valid. UserName='******'.", token.UserName); // create an exception with a vendor defined sub-code. throw new ServiceResultException(new ServiceResult( StatusCodes.BadUserAccessDenied, "InvalidUserInformation", "http://opcfoundation.org", new LocalizedText(info))); } break; default: break; } }