/// <summary> /// Sets SSO token. Default implementation sets browser cookie /// </summary> protected virtual void SetSsoSessionId(LoginFlow loginFlow, string ssoSessionName) { var cookie = new Cookie(ssoSessionName, loginFlow.SsoSessionId); cookie.HttpOnly = true; cookie.Secure = true ^ WebOptions.Of("cookie-not-secure").ValueAsBool(false); cookie.Expires = App.TimeSource.UTCNow.AddMinutes(WebOptions.Of("cookie-expire-in-minutes").ValueAsDouble(2 * 24 * 60)); WorkContext.Response.AppendCookie(cookie); }
protected async virtual Task SetSsoSubjectSessionAsync(LoginFlow loginFlow, DateTime lastLoginUtc, User ssoSubjectUser) { loginFlow.SsoWasJustSet = true; loginFlow.SsoSubjectLastLoginUtc = lastLoginUtc; loginFlow.SsoSubjectUser = ssoSubjectUser; var session = OAuth.TokenRing.GenerateNew <SsoSessionToken>(); session.SysAuthToken = loginFlow.SsoSubjectUser.AuthToken.ToString(); loginFlow.SsoSessionId = await OAuth.TokenRing.PutAsync(session).ConfigureAwait(false); }
/// <summary> /// Override to provide a authorize result which is by default either a stock login form or /// JSON object /// </summary> protected virtual object MakeAuthorizeResult(LoginFlow loginFlow, string roundtrip, string error) { if (WorkContext.RequestedJson) { return new { OK = error.IsNullOrEmpty(), roundtrip, error } } ; //stock log-in page return(new Wave.Templatization.StockContent.OAuthLogin(loginFlow.ClientUser, roundtrip, error)); }
/// <summary> /// Advances login flow state to the next level. /// You may override this and accompanying "RespondWithAuthorizeResult/MakeAuthorizeResult"/> /// method to build a complex login flows which return different views, such as 2FA etc. /// </summary> protected virtual Task AdvanceLoginFlowStateAsync(LoginFlow loginFlow) { if (loginFlow.IsValidSsoUser) { loginFlow.FiniteStateSuccess = true; } if (loginFlow.IsValidSubjectUser) { loginFlow.FiniteStateSuccess = true; } return(Task.CompletedTask); }
protected virtual object RespondWithAuthorizeResult(long sdUtc, LoginFlow loginFlow, string error) { //Pack all requested content(session) into cryptographically encoded message aka "roundtrip" var flow = new { sd = sdUtc, iss = App.TimeSource.UTCNow.ToSecondsSinceUnixEpochStart(), tp = loginFlow.ClientResponseType, scp = loginFlow.ClientScope, id = loginFlow.ClientId, uri = loginFlow.ClientRedirectUri, st = loginFlow.ClientState }; var roundtrip = App.SecurityManager.PublicProtectAsString(flow); if (error != null) { WorkContext.Response.StatusCode = WebConsts.STATUS_403; WorkContext.Response.StatusDescription = error; } return(MakeAuthorizeResult(loginFlow, roundtrip, error)); }
/// <summary> /// Tries to get SSO subject user by examining the supplied idSsoSession. /// Set sso user to NULL if the SSO session id is invalid/or user revoked etc.. /// </summary> protected async virtual Task TryGetSsoSubjectAsync(LoginFlow loginFlow) { var session = await OAuth.TokenRing.GetAsync <SsoSessionToken>(loginFlow.SsoSessionId).ConfigureAwait(false); if (session == null) { return; } if (!SysAuthToken.TryParse(session.SysAuthToken, out var sysToken)) { return; } var ssoSubject = await App.SecurityManager.AuthenticateAsync(sysToken).ConfigureAwait(false); if (!ssoSubject.IsAuthenticated) { return; //sys auth token may have expired } loginFlow.SsoSubjectUser = ssoSubject; }
/// <summary> /// Override to extract SSO session cookie from the request. The value (if any) is set on `loginFlow.SsoSessionId` /// Default implementation uses Request Cookie named OAuth.SsoSessionName if it is set. /// You must set loginFlow.SsoSessionId to null if there is no such session id provided or OAuth.ssoSessionName is turned off (null or whitespace) /// </summary> protected virtual void TryExtractSsoSessionId(LoginFlow loginFlow) { var ssoCookieName = OAuth.SsoSessionName;//copy if (ssoCookieName.IsNullOrWhiteSpace()) { return; } var cookie = WorkContext.Request.Cookies[ssoCookieName]; if (cookie == null) { return; } var result = cookie.Value; if (result.IsNullOrWhiteSpace()) { return; } loginFlow.SsoSessionId = result; }
/// <summary> /// Override to add extra information to <see cref="AuthenticationRequestContext"/>. /// Default implementation does nothing /// </summary> protected virtual void ConfigureAuthenticationRequestContext(LoginFlow loginFlow, AuthenticationRequestContext context) { }
/// <summary> /// Override to return a 403 (unauthorized result) of user logout /// </summary> protected virtual object ReturnSsoLogout403(LoginFlow flow) { return(new Http403Forbidden()); }