Beispiel #1
0
        internal async Task <TResult> CreateCredentialMappingAsync <TResult>(Guid credentialMappingId,
                                                                             CredentialValidationMethodTypes method, string subjectId, Guid actorId,
                                                                             Func <TResult> onSuccess,
                                                                             Func <TResult> onAlreadyExists,
                                                                             Func <TResult> onTokenAlreadyInUse)
        {
            var rollback = new RollbackAsync <TResult>();

            var methodName           = Enum.GetName(typeof(CredentialValidationMethodTypes), method);
            var credentialMappingDoc = new Documents.CredentialMappingDocument()
            {
                Method  = methodName,
                Subject = subjectId,
                ActorId = actorId,
            };

            rollback.AddTaskCreate(credentialMappingId, credentialMappingDoc, onAlreadyExists, this.repository);

            var lookupDocument = new Azure.Documents.CredentialMappingLookupDocument()
            {
                CredentialMappingId = credentialMappingId,
                Method  = methodName,
                Subject = subjectId,
            };

            rollback.AddTaskCreate(subjectId, methodName, lookupDocument, onTokenAlreadyInUse, this.repository);

            rollback.AddTaskCreateOrUpdate(actorId,
                                           (Documents.ActorMappingsDocument authDoc) => authDoc.AddInviteId(credentialMappingId),
                                           (authDoc) => authDoc.RemoveInviteId(credentialMappingId),
                                           onAlreadyExists, // This should fail on the action above as well
                                           this.repository);

            return(await rollback.ExecuteAsync(onSuccess));
        }
Beispiel #2
0
        public async Task <TResult> CreateAsync <TResult>(Guid integrationId, Guid accountId,
                                                          CredentialValidationMethodTypes method, IDictionary <string, string> paramSet,
                                                          Func <TResult> onSuccess,
                                                          Func <TResult> onAlreadyExists)
        {
            var methodName  = Enum.GetName(typeof(CredentialValidationMethodTypes), method);
            var docByMethod = new AccessDocument
            {
                LookupId = integrationId,
                Method   = methodName,
            };

            docByMethod.SetExtraParams(paramSet);
            var docById = new AccessDocument
            {
                LookupId = accountId,
                Method   = methodName,
            };

            docById.SetExtraParams(paramSet);
            var rollback = new RollbackAsync <TResult>();

            rollback.AddTaskCreate(accountId, methodName, docByMethod, onAlreadyExists, this.repository);
            rollback.AddTaskCreate(integrationId, docById, onAlreadyExists, this.repository);
            return(await rollback.ExecuteAsync(onSuccess));
        }
        public async Task <TResult> CreateAsync <TResult>(Guid authenticationRequestId,
                                                          CredentialValidationMethodTypes method, AuthenticationActions action,
                                                          Guid actorLinkId, string token, Uri redirectUrl, Uri redirectLogoutUrl,
                                                          Func <TResult> onSuccess,
                                                          Func <TResult> onAlreadyExists)
        {
            var doc = new Documents.AuthenticationRequestDocument
            {
                Method = Enum.GetName(typeof(CredentialValidationMethodTypes), method),
                Action = Enum.GetName(typeof(AuthenticationActions), action),
                LinkedAuthenticationId = actorLinkId,
                Token       = token,
                RedirectUrl = redirectUrl.IsDefault() ?
                              default(string)
                    :
                              redirectUrl.AbsoluteUri,
                RedirectLogoutUrl = redirectLogoutUrl.IsDefault() ?
                                    default(string)
                    :
                                    redirectLogoutUrl.AbsoluteUri,
            };

            return(await this.repository.CreateAsync(authenticationRequestId, doc,
                                                     () => onSuccess(),
                                                     () => onAlreadyExists()));
        }
Beispiel #4
0
        public async Task <TResult> LookupCredentialMappingAsync <TResult>(
            CredentialValidationMethodTypes method, string subject, Guid?loginId,
            Func <Guid, TResult> onSuccess,
            Func <TResult> onNotExist)
        {
            var partitionKey = Enum.GetName(typeof(CredentialValidationMethodTypes), method);

            return(await await repository.FindLinkedDocumentAsync(subject, partitionKey,
                                                                  (Azure.Documents.CredentialMappingLookupDocument document) => document.CredentialMappingId,
                                                                  (Azure.Documents.CredentialMappingLookupDocument lookupDoc, Documents.CredentialMappingDocument mappingDoc) =>
                                                                  onSuccess(mappingDoc.ActorId).ToTask(),
                                                                  async() => loginId.HasValue?
                                                                  await await repository.FindByIdAsync(loginId.Value,
                                                                                                       (Documents.LoginActorLookupDocument document) =>
            {
                // Migrate this by creating a CredentialMappingLookupDoc with the subject/partitionKey(method)
                return CreateCredentialMappingAsync(Guid.NewGuid(), method, subject, document.ActorId,
                                                    () => onSuccess(document.ActorId),
                                                    () => onSuccess(document.ActorId),
                                                    () => onSuccess(document.ActorId));
            },
                                                                                                       onNotExist.AsAsyncFunc())
                                                                  :
                                                                  onNotExist(),
                                                                  () => onNotExist().ToTask()));
        }
        internal async Task <TResult> UpdateAsync <TResult>(Persistence.AuthenticationRequest authenticationRequest,
                                                            Guid sessionId, Guid stateId,
                                                            CredentialValidationMethodTypes method, IDictionary <string, string> extraParams,
                                                            Func <Guid, string, IDictionary <string, string>, Task> saveAuthRequest,
                                                            Func <Guid, Guid, string, string, AuthenticationActions, IDictionary <string, string>, Uri, TResult> onSuccess,
                                                            Func <string, TResult> onInvalidToken,
                                                            Func <string, TResult> onNotConfigured,
                                                            Func <string, TResult> onFailure)
        {
            if (!authenticationRequest.authorizationId.HasValue)
            {
                return(onFailure("The credential is corrupt"));
            }

            var authenticationId = authenticationRequest.authorizationId.Value;

            return(await await dataContext.Accesses.CreateAsync(authenticationRequest.id, authenticationId,
                                                                method, extraParams,
                                                                async() => await await context.Sessions.CreateSessionAsync(sessionId, authenticationId,
                                                                                                                           async(token, refreshToken) =>
            {
                await saveAuthRequest(authenticationId, token, extraParams);
                return onSuccess(stateId, authenticationId, token, refreshToken,
                                 AuthenticationActions.access, extraParams,
                                 authenticationRequest.redirect);
            },
                                                                                                                           onNotConfigured.AsAsyncFunc()),
                                                                () => onInvalidToken("Login is already mapped to an access.").ToTask()));
        }
Beispiel #6
0
 internal async Task <TResult> CreateLoginAsync <TResult>(Guid authenticationRequestId, Guid authenticationId,
                                                          CredentialValidationMethodTypes method, Uri callbackLocation, IDictionary <string, string> authParams,
                                                          Func <Session, TResult> onSuccess,
                                                          Func <TResult> onAlreadyExists,
                                                          Func <string, TResult> onFailure)
 {
     return(await EastFive.Web.Configuration.Settings.GetUri(
                EastFive.Security.AppSettings.TokenScope,
                async (scope) =>
     {
         var sessionId = SecureGuid.Generate();
         var claims = await this.context.Claims.FindByAccountIdAsync(authenticationId,
                                                                     (cs) => cs.Select(c => c.Type.PairWithValue(c.Value)).ToDictionary(),
                                                                     () => new Dictionary <string, string>());
         return await Sessions.GenerateToken(sessionId, authenticationId, claims,
                                             (token) => this.dataContext.AuthenticationRequests.CreateAsync(authenticationRequestId,
                                                                                                            method, AuthenticationActions.signin, authenticationId, token, callbackLocation, callbackLocation,
                                                                                                            () =>
         {
             telemetry.TrackEvent("Sessions.CreateLoginAsync - Create Session", authParams);
             var session = new Session()
             {
                 id = authenticationRequestId,
                 method = method,
                 action = AuthenticationActions.signin,
                 token = token,
                 extraParams = authParams
             };
             return onSuccess(session);
         },
                                                                                                            onAlreadyExists),
                                             why => onFailure(why).ToTask());
     },
                onFailure.AsAsyncFunc()));
 }
 public async Task <TResult> GetParamsByActorAsync <TResult>(Guid actorId, CredentialValidationMethodTypes method,
                                                             Func <Guid, IDictionary <string, string>, Func <IDictionary <string, string>, Task>, Task <TResult> > onSuccess,
                                                             Func <TResult> onNotFound)
 {
     return(await this.dataContext.Accesses.FindUpdatableAsync(actorId, method,
                                                               onSuccess,
                                                               onNotFound));
 }
 private static Resources.AuthenticationRequestLink Convert(CredentialValidationMethodTypes method, UrlHelper urlHelper)
 {
     return(new Resources.AuthenticationRequestLink
     {
         Id = urlHelper.GetWebId <Controllers.SessionController>(SecureGuid.Generate()),
         Method = method,
         Name = method.ToString(),
         SecureId = SecureGuid.Generate(),
     });
 }
Beispiel #9
0
        public async Task <TResult> FindAsync <TResult>(Guid actorId, CredentialValidationMethodTypes method,
                                                        Func <Guid, IDictionary <string, string>, TResult> found,
                                                        Func <TResult> actorNotFound)
        {
            var methodName = Enum.GetName(typeof(CredentialValidationMethodTypes), method);
            var results    = await repository.FindByIdAsync(actorId, methodName,
                                                            (AccessDocument doc) => found(doc.LookupId, doc.GetExtraParams()),
                                                            () => actorNotFound());

            return(results);
        }
Beispiel #10
0
        public async Task <TResult> LookupCredentialMappingAsync <TResult>(
            CredentialValidationMethodTypes method, string subject, Guid?loginId, Guid sessionId,
            IDictionary <string, string> extraParams,
            Func <Guid, string, string, IDictionary <string, string>, TResult> onSuccess,
            Func <TResult> alreadyExists,
            Func <TResult> credentialNotInSystem,
            Func <string, TResult> onConfigurationFailure)
        {
            // Convert authentication unique ID to Actor ID
            var resultLookup = await await dataContext.CredentialMappings.LookupCredentialMappingAsync(method, subject, loginId,
                                                                                                       (actorId) => CreateSessionAsync(sessionId, actorId,
                                                                                                                                       (token, refreshToken) => onSuccess(actorId, token, refreshToken, extraParams),
                                                                                                                                       onConfigurationFailure),
                                                                                                       () => credentialNotInSystem().ToTask());

            return(resultLookup);
        }
        public static async Task <TResult> ResponseGetAsync <TResult>(this ITestSession session,
                                                                      CredentialValidationMethodTypes method, IDictionary <string, string> extraParams,
                                                                      Func <HttpResponseMessage, TResult> callback)
        {
            var query = new ResponseResult
            {
                method = method,
            };
            var response = await session.GetAsync <ResponseController>(query,
                                                                       (request) =>
            {
                request.RequestUri = extraParams.Aggregate(
                    request.RequestUri,
                    (requestUri, queryParam) => requestUri.SetQueryParam(queryParam.Key, queryParam.Value));
            });

            return(callback(response));
        }
        internal async Task <TResult> CreateAsync <TResult>(Guid credentialId, Guid authenticationId,
                                                            CredentialValidationMethodTypes method, string subject,
                                                            Guid performingActorId, System.Security.Claims.Claim[] claims,
                                                            Func <TResult> onSuccess,
                                                            Func <Guid, TResult> onAlreadyExists,
                                                            Func <TResult> onSubjectAlreadyInUse,
                                                            Func <TResult> onUnauthorized,
                                                            Func <string, TResult> onFailure)
        {
            if (!await Library.configurationManager.CanAdministerCredentialAsync(authenticationId, performingActorId, claims))
            {
                return(onUnauthorized());
            }

            return(await this.dataContext.CredentialMappings.CreateCredentialMappingAsync(credentialId, method, subject, authenticationId,
                                                                                          onSuccess,
                                                                                          () => onAlreadyExists(credentialId),
                                                                                          onSubjectAlreadyInUse));
        }
        internal TResult GetLoginProvider <TResult>(CredentialValidationMethodTypes method,
                                                    Func <IProvideLogin, TResult> onSuccess,
                                                    Func <TResult> onCredintialSystemNotAvailable,
                                                    Func <string, TResult> onFailure)
        {
            if (ServiceConfiguration.loginProviders.IsDefault())
            {
                return(onFailure("Authentication system not initialized."));
            }

            if (!ServiceConfiguration.loginProviders.ContainsKey(method))
            {
                return(onCredintialSystemNotAvailable());
            }

            var provider = ServiceConfiguration.loginProviders[method];

            return(onSuccess(provider));
        }
Beispiel #14
0
        public async Task <TResult> FindUpdatableAsync <TResult>(Guid actorId, CredentialValidationMethodTypes method,
                                                                 Func <Guid, IDictionary <string, string>, Func <IDictionary <string, string>, Task>, Task <TResult> > onFound,
                                                                 Func <TResult> actorNotFound)
        {
            var methodName = Enum.GetName(typeof(CredentialValidationMethodTypes), method);
            var results    = await repository.UpdateAsync <AccessDocument, TResult>(actorId, methodName,
                                                                                    async (doc, saveAsync) =>
            {
                return(await onFound(doc.LookupId, doc.GetExtraParams(),
                                     async(extraParamsNew) =>
                {
                    doc.SetExtraParams(extraParamsNew);
                    await saveAsync(doc);
                }));
            },
                                                                                    () => actorNotFound());

            return(results);
        }
 public async Task <TResult> CreateLinkAsync <TResult>(Guid authenticationRequestId,
                                                       Uri callbackLocation,
                                                       CredentialValidationMethodTypes method, Uri redirectUrl,
                                                       Guid authenticationId, Guid actorId, System.Security.Claims.Claim[] claims,
                                                       Func <Session, TResult> onSuccess,
                                                       Func <TResult> onAlreadyExists,
                                                       Func <string, TResult> onUnauthorized,
                                                       Func <TResult> onCredentialSystemNotAvailable,
                                                       Func <string, TResult> onCredentialSystemNotInitialized,
                                                       Func <string, TResult> onFailure)
 {
     if (!await Library.configurationManager.CanAdministerCredentialAsync(authenticationId, actorId, claims))
     {
         return(onUnauthorized($"Provided token does not permit access to link {authenticationId} to a login"));
     }
     return(await context.GetLoginProvider(method,
                                           async (provider) =>
     {
         var sessionId = SecureGuid.Generate();
         return await BlackBarLabs.Security.Tokens.JwtTools.CreateToken(sessionId, callbackLocation, TimeSpan.FromMinutes(30),
                                                                        (token) => this.dataContext.AuthenticationRequests.CreateAsync(authenticationRequestId,
                                                                                                                                       method, AuthenticationActions.access, authenticationId, token, redirectUrl, redirectUrl,
                                                                                                                                       () => onSuccess(
                                                                                                                                           new Session()
         {
             id = authenticationRequestId,
             method = method,
             action = AuthenticationActions.access,
             loginUrl = provider.GetLoginUrl(authenticationRequestId, callbackLocation),
             logoutUrl = provider.GetLogoutUrl(authenticationRequestId, callbackLocation),
             redirectUrl = redirectUrl,
             authorizationId = authenticationId,
             token = token,
         }),
                                                                                                                                       onAlreadyExists),
                                                                        why => onFailure(why).ToTask(),
                                                                        (param, why) => onFailure($"Invalid configuration for {param}:{why}").ToTask());
     },
                                           onCredentialSystemNotAvailable.AsAsyncFunc(),
                                           onCredentialSystemNotInitialized.AsAsyncFunc()));
 }
Beispiel #16
0
        public async Task <TResult> DeleteAsync <TResult>(Guid actorId, CredentialValidationMethodTypes method,
                                                          Func <CredentialValidationMethodTypes, IDictionary <string, string>, TResult> onDeleted,
                                                          Func <TResult> actorNotFound)
        {
            var methodName = Enum.GetName(typeof(CredentialValidationMethodTypes), method);
            var results    = await repository.DeleteIfAsync <AccessDocument, TResult>(actorId, methodName,
                                                                                      async (doc, deleteAsync) =>
            {
                await deleteAsync();
                return(await repository.DeleteIfAsync <AccessDocument, TResult>(doc.LookupId,
                                                                                async(lookupDoc, deleteLookupAsync) =>
                {
                    await deleteLookupAsync();
                    return onDeleted(method, doc.GetExtraParams());
                },
                                                                                () => onDeleted(method, doc.GetExtraParams())));
            },
                                                                                      () => actorNotFound());

            return(results);
        }
Beispiel #17
0
 public async Task <TResult> CreateLoginAsync <TResult>(Guid authenticationRequestId,
                                                        CredentialValidationMethodTypes method, Uri redirectUrl, Uri redirectLogoutUrl,
                                                        Func <Type, Uri> controllerToLocation,
                                                        Func <Session, TResult> onSuccess,
                                                        Func <TResult> onAlreadyExists,
                                                        Func <TResult> onCredentialSystemNotAvailable,
                                                        Func <string, TResult> onCredentialSystemNotInitialized,
                                                        Func <string, TResult> onFailure)
 {
     return(await context.GetLoginProvider(method,
                                           async (provider) =>
     {
         var callbackLocation = controllerToLocation(provider.CallbackController);
         var sessionId = SecureGuid.Generate();
         var result = await this.dataContext.AuthenticationRequests.CreateAsync(authenticationRequestId,
                                                                                method, AuthenticationActions.signin, redirectUrl, redirectLogoutUrl,
                                                                                () => BlackBarLabs.Security.Tokens.JwtTools.CreateToken(sessionId, callbackLocation, TimeSpan.FromMinutes(30),
                                                                                                                                        (token) =>
         {
             var session = new Session()
             {
                 id = authenticationRequestId,
                 method = method,
                 action = AuthenticationActions.signin,
                 loginUrl = provider.GetLoginUrl(authenticationRequestId, callbackLocation),
                 logoutUrl = provider.GetLogoutUrl(authenticationRequestId, callbackLocation),
                 redirectUrl = redirectUrl,
                 redirectLogoutUrl = redirectLogoutUrl,
                 token = token,
             };
             return onSuccess(session);
         },
                                                                                                                                        why => onFailure(why),
                                                                                                                                        (param, why) => onFailure($"Invalid configuration for {param}:{why}")),
                                                                                onAlreadyExists);
         return result;
     },
                                           onCredentialSystemNotAvailable.AsAsyncFunc(),
                                           onCredentialSystemNotInitialized.AsAsyncFunc()));
 }
        public virtual async Task <TResult> GetRedirectUriAsync <TResult>(Context context,
                                                                          CredentialValidationMethodTypes validationType,
                                                                          AuthenticationActions action,
                                                                          Guid requestId,
                                                                          Guid?authorizationId,
                                                                          string token, string refreshToken,
                                                                          IDictionary <string, string> authParams,
                                                                          Uri redirectUriFromPost,
                                                                          Func <Uri, TResult> onSuccess,
                                                                          Func <string, string, TResult> onInvalidParameter,
                                                                          Func <string, TResult> onFailure)
        {
            if (!redirectUriFromPost.IsDefault())
            {
                var redirectUrl = SetRedirectParameters(redirectUriFromPost, requestId, authorizationId, token, refreshToken);
                return(onSuccess(redirectUrl));
            }

            if (null != authParams && authParams.ContainsKey(Configuration.AuthorizationParameters.RedirectUri))
            {
                Uri redirectUri;
                var redirectUriString = authParams[Configuration.AuthorizationParameters.RedirectUri];
                if (!Uri.TryCreate(redirectUriString, UriKind.Absolute, out redirectUri))
                {
                    return(onInvalidParameter("REDIRECT", $"BAD URL in redirect call:{redirectUriString}"));
                }
                var redirectUrl = SetRedirectParameters(redirectUri, requestId, authorizationId, token, refreshToken);
                return(onSuccess(redirectUrl));
            }

            return(await EastFive.Web.Configuration.Settings.GetUri(
                       EastFive.Security.SessionServer.Configuration.AppSettings.LandingPage,
                       (redirectUri) =>
            {
                var redirectUrl = SetRedirectParameters(redirectUri, requestId, authorizationId, token, refreshToken);
                return onSuccess(redirectUrl);
            },
                       (why) => onFailure(why)).ToTask());
        }
        private async Task <IHttpActionResult> CreateResponse(Context context,
                                                              CredentialValidationMethodTypes method, AuthenticationActions action,
                                                              Guid sessionId, Guid?authorizationId, string jwtToken, string refreshToken,
                                                              IDictionary <string, string> extraParams, Uri redirectUrl, TelemetryClient telemetry)
        {
            var config           = Library.configurationManager;
            var redirectResponse = await config.GetRedirectUriAsync(context, method, action,
                                                                    sessionId, authorizationId, jwtToken, refreshToken, extraParams,
                                                                    redirectUrl,
                                                                    (redirectUrlSelected) =>
            {
                telemetry.TrackEvent($"CreateResponse - redirectUrlSelected1: {redirectUrlSelected.AbsolutePath}");
                telemetry.TrackEvent($"CreateResponse - redirectUrlSelected2: {redirectUrlSelected.AbsoluteUri}");
                return(Redirect(redirectUrlSelected));
            },
                                                                    (paramName, why) =>
            {
                var message = $"Invalid parameter while completing login: {paramName} - {why}";
                telemetry.TrackException(new ResponseException(message));
                return(Request.CreateResponse(HttpStatusCode.BadRequest, message)
                       .AddReason(why)
                       .ToActionResult());
            },
                                                                    (why) =>
            {
                var message = $"General failure while completing login: {why}";
                telemetry.TrackException(new ResponseException(message));
                return(Request.CreateResponse(HttpStatusCode.BadRequest, message)
                       .AddReason(why)
                       .ToActionResult());
            });

            var msg = redirectResponse;

            telemetry.TrackEvent($"CreateResponse - {msg}");
            return(redirectResponse);
        }
        protected async Task <IHttpActionResult> ProcessRequestAsync(CredentialValidationMethodTypes method,
                                                                     IDictionary <string, string> values)
        {
            var telemetry = Web.Configuration.Settings.GetString(SessionServer.Configuration.AppSettings.ApplicationInsightsKey,
                                                                 (applicationInsightsKey) =>
            {
                return(new TelemetryClient {
                    InstrumentationKey = applicationInsightsKey
                });
            },
                                                                 (why) =>
            {
                return(new TelemetryClient());
            });

            var context  = this.Request.GetSessionServerContext();
            var response = await await context.Sessions.CreateOrUpdateWithAuthenticationAsync(
                method, values,
                async (sessionId, authorizationId, jwtToken, refreshToken, action, extraParams, redirectUrl) =>
            {
                telemetry.TrackEvent($"ResponseController.ProcessRequestAsync - Created Authentication.  Creating response.");
                var resp = await CreateResponse(context, method, action, sessionId, authorizationId, jwtToken, refreshToken, extraParams, redirectUrl, telemetry);
                return(resp);
            },
                (location) =>
            {
                telemetry.TrackEvent($"ResponseController.ProcessRequestAsync - location: {location.AbsolutePath}");
                if (location.IsDefaultOrNull())
                {
                    return(Web.Configuration.Settings.GetUri(SessionServer.Configuration.AppSettings.LandingPage,
                                                             (redirect) => ((IHttpActionResult)Redirect(location))
                                                             .ToTask(),
                                                             (why) => this.Request.CreateResponse(HttpStatusCode.BadRequest, why)
                                                             .AddReason($"Location was null")
                                                             .ToActionResult()
                                                             .ToTask()));
                }
                if (location.Query.IsNullOrWhiteSpace())
                {
                    location = location.SetQueryParam("cache", Guid.NewGuid().ToString("N"));
                }
                return(((IHttpActionResult)Redirect(location)).ToTask());
            },
                (why) =>
            {
                var message = $"Invalid token:{why}";
                telemetry.TrackException(new ResponseException());
                return(this.Request.CreateResponse(HttpStatusCode.BadRequest, message)
                       .AddReason($"Invalid token:{why}")
                       .ToActionResult()
                       .ToTask());
            },
                () =>
            {
                var message = "Token is not connected to a user in this system";
                telemetry.TrackException(new ResponseException(message));
                return(this.Request.CreateResponse(HttpStatusCode.Conflict)
                       .AddReason(message)
                       .ToActionResult()
                       .ToTask());
            },
                (why) =>
            {
                var message = $"Cannot create session because service is unavailable: {why}";
                telemetry.TrackException(new ResponseException(message));
                return(this.Request.CreateResponse(HttpStatusCode.ServiceUnavailable, message)
                       .AddReason(why)
                       .ToActionResult()
                       .ToTask());
            },
                (why) =>
            {
                var message = $"Cannot create session because service is unavailable: {why}";
                telemetry.TrackException(new ResponseException(message));
                return(this.Request.CreateResponse(HttpStatusCode.ServiceUnavailable, message)
                       .AddReason(why)
                       .ToActionResult()
                       .ToTask());
            },
                (why) =>
            {
                var message = $"General failure: {why}";
                telemetry.TrackException(new ResponseException(message));
                return(this.Request.CreateResponse(HttpStatusCode.Conflict, message)
                       .AddReason(why)
                       .ToActionResult()
                       .ToTask());
            });

            return(response);
        }
        public async Task <TResult> CreateInviteCredentialAsync <TResult>(Guid sessionId, Guid?stateId,
                                                                          Guid?authorizationId, CredentialValidationMethodTypes method, string subject,
                                                                          IDictionary <string, string> extraParams,
                                                                          Func <Guid, string, IDictionary <string, string>, Task> saveAuthRequest,
                                                                          Uri redirectUrl,
                                                                          Func <Guid, Guid, string, string, AuthenticationActions, IDictionary <string, string>, Uri, TResult> onLogin,
                                                                          Func <string, TResult> onInvalidToken,
                                                                          Func <string, TResult> onNotConfigured,
                                                                          Func <string, TResult> onFailure)
        {
            if (!authorizationId.HasValue)
            {
                return(onFailure("The credential is corrupt"));
            }

            var authenticationId = authorizationId.Value;

            return(await await dataContext.CredentialMappings.CreateCredentialMappingAsync(Guid.NewGuid(), method, subject,
                                                                                           authorizationId.Value,
                                                                                           async() => await await context.Sessions.CreateSessionAsync(sessionId, authenticationId,
                                                                                                                                                      async(token, refreshToken) =>
            {
                await saveAuthRequest(authenticationId, token, extraParams);
                return onLogin(stateId.Value, authenticationId, token, refreshToken, AuthenticationActions.link, extraParams,
                               redirectUrl);
            },
                                                                                                                                                      onNotConfigured.AsAsyncFunc()),
                                                                                           "GUID not unique".AsFunctionException <Task <TResult> >(),
                                                                                           () => onInvalidToken("Login is already mapped.").ToTask()));
        }
Beispiel #22
0
        public async Task <TResult> UpdateWithAuthenticationAsync <TResult>(
            Guid sessionId,
            CredentialValidationMethodTypes method,
            IDictionary <string, string> extraParams,
            Func <Guid, Guid, string, string, AuthenticationActions, IDictionary <string, string>, Uri, TResult> onLogin,
            Func <Uri, TResult> onLogout,
            Func <string, TResult> onInvalidToken,
            Func <TResult> lookupCredentialNotFound,
            Func <string, TResult> systemOffline,
            Func <string, TResult> onNotConfigured,
            Func <string, TResult> onFailure)
        {
            return(await this.context.GetCredentialProvider(method,
                                                            async (provider) =>
            {
                return await await provider.RedeemTokenAsync(extraParams,
                                                             async(subject, stateId, loginId, extraParamsWithRedemptionParams) =>
                {
                    if (stateId.HasValue)
                    {
                        if (stateId.Value != sessionId)
                        {
                            return onInvalidToken("The authorization flow did not match this resource");
                        }

                        return await AuthenticateStateAsync(stateId.Value, loginId, method, subject, extraParamsWithRedemptionParams,
                                                            onLogin,
                                                            onLogout,
                                                            onInvalidToken,
                                                            onNotConfigured,
                                                            onFailure);
                    }

                    return await await dataContext.CredentialMappings.LookupCredentialMappingAsync(method, subject, loginId,
                                                                                                   (authenticationId) =>
                    {
                        return context.Sessions.CreateSessionAsync(sessionId, authenticationId,
                                                                   (token, refreshToken) => onLogin(sessionId, authenticationId,
                                                                                                    token, refreshToken, AuthenticationActions.signin, extraParamsWithRedemptionParams,
                                                                                                    default(Uri)), // No redirect URL is available since an AuthorizationRequest was not provided
                                                                   onNotConfigured);
                    },
                                                                                                   () => onInvalidToken("The token does not map to a user in this system.").ToTask());
                },
                                                             async(stateId, extraParamsWithRedemptionParams) =>
                {
                    if (!stateId.HasValue)
                    {
                        onLogout(default(Uri));
                    }

                    return await dataContext.AuthenticationRequests.FindByIdAsync(stateId.Value,
                                                                                  (authRequest) => onLogout(authRequest.redirectLogout),
                                                                                  () => onLogout(default(Uri)));
                },
                                                             onInvalidToken.AsAsyncFunc(),
                                                             systemOffline.AsAsyncFunc(),
                                                             onNotConfigured.AsAsyncFunc(),
                                                             onFailure.AsAsyncFunc());
            },
                                                            () => systemOffline("The requested credential system is not enabled for this deployment").ToTask(),
                                                            (why) => onNotConfigured(why).ToTask()));
        }
Beispiel #23
0
        public async Task <TResult> CreateOrUpdateWithAuthenticationAsync <TResult>(
            CredentialValidationMethodTypes method,
            IDictionary <string, string> extraParams,
            Func <Guid, Guid, string, string, AuthenticationActions, IDictionary <string, string>, Uri, TResult> onLogin,
            Func <Uri, TResult> onLogout,
            Func <string, TResult> onInvalidToken,
            Func <TResult> lookupCredentialNotFound,
            Func <string, TResult> systemOffline,
            Func <string, TResult> onNotConfigured,
            Func <string, TResult> onFailure)
        {
            return(await this.context.GetCredentialProvider(method,
                                                            async (provider) =>
            {
                return await await provider.RedeemTokenAsync(extraParams,
                                                             async(subject, stateId, loginId, extraParamsWithRedemptionParams) =>
                {
                    telemetry.TrackEvent("Sessions.CreateOrUpdateWithAuthenticationAsync:  Authenticated", extraParamsWithRedemptionParams);
                    // This is the case where the login process started from an existing authentication resource
                    if (stateId.HasValue)
                    {
                        telemetry.TrackEvent($"Sessions.CreateOrUpdateWithAuthenticationAsync:  StateId: {stateId.Value.ToString()}");
                        return await AuthenticateStateAsync(stateId.Value, loginId, method, subject, extraParamsWithRedemptionParams,
                                                            onLogin,
                                                            onLogout,
                                                            onInvalidToken,
                                                            onNotConfigured,
                                                            onFailure);
                    }
                    // This is the case where the login process started from an external system
                    telemetry.TrackEvent("StateId not found.  Starting external system login flow.");
                    return await await dataContext.CredentialMappings.LookupCredentialMappingAsync(method, subject, loginId,
                                                                                                   (authenticationId) =>
                    {
                        telemetry.TrackEvent($"Sessions.CreateOrUpdateWithAuthenticationAsync:  Called from external login system.  AuthenticationId: {authenticationId.ToString()}");
                        var authorizationId = Guid.NewGuid();
                        return this.CreateLoginAsync(authorizationId, authenticationId, method, default(Uri), extraParamsWithRedemptionParams,
                                                     (session) => onLogin(authorizationId, authenticationId, session.token, session.refreshToken, AuthenticationActions.signin, session.extraParams,
                                                                          default(Uri)),
                                                     "Guid not unique for creating authentication started from external system".AsFunctionException <TResult>(),
                                                     onFailure);
                    },
                                                                                                   () => onInvalidToken("The token does not map to a user in this system.").ToTask());
                },
                                                             async(stateId, extraParamsWithRedemptionParams) =>
                {
                    telemetry.TrackEvent("Sessions.CreateOrUpdateWithAuthenticationAsync:  Not Authenticated");
                    if (!stateId.HasValue)
                    {
                        onLogout(default(Uri));
                    }

                    return await dataContext.AuthenticationRequests.FindByIdAsync(stateId.Value,
                                                                                  (authRequest) => onLogout(authRequest.redirectLogout),
                                                                                  () => onLogout(default(Uri)));
                },
                                                             onInvalidToken.AsAsyncFunc(),
                                                             systemOffline.AsAsyncFunc(),
                                                             onNotConfigured.AsAsyncFunc(),
                                                             onFailure.AsAsyncFunc());
            },
                                                            () => systemOffline("The requested credential system is not enabled for this deployment").ToTask(),
                                                            (why) => onNotConfigured(why).ToTask()));
        }
Beispiel #24
0
        private async Task <TResult> AuthenticateStateAsync <TResult>(Guid sessionId, Guid?loginId, CredentialValidationMethodTypes method,
                                                                      string subject, IDictionary <string, string> extraParams,
                                                                      Func <Guid, Guid, string, string, AuthenticationActions, IDictionary <string, string>, Uri, TResult> onLogin,
                                                                      Func <Uri, TResult> onLogout,
                                                                      Func <string, TResult> onInvalidToken,
                                                                      Func <string, TResult> onNotConfigured,
                                                                      Func <string, TResult> onFailure)
        {
            return(await this.dataContext.AuthenticationRequests.UpdateAsync(sessionId,
                                                                             async (authenticationRequest, saveAuthRequest) =>
            {
                if (authenticationRequest.Deleted.HasValue)
                {
                    return onLogout(authenticationRequest.redirectLogout);
                }

                if (authenticationRequest.method != method)
                {
                    return onInvalidToken("The credential's authentication method does not match the callback method");
                }

                if (AuthenticationActions.link == authenticationRequest.action)
                {
                    return await context.Invites.CreateInviteCredentialAsync(sessionId, sessionId,
                                                                             authenticationRequest.authorizationId, method, subject,
                                                                             extraParams, saveAuthRequest, authenticationRequest.redirect,
                                                                             onLogin,
                                                                             onInvalidToken,
                                                                             onNotConfigured,
                                                                             onFailure);
                }

                if (AuthenticationActions.access == authenticationRequest.action)
                {
                    return await context.Integrations.UpdateAsync(authenticationRequest,
                                                                  sessionId, sessionId, method, extraParams,
                                                                  saveAuthRequest,
                                                                  onLogin,
                                                                  onInvalidToken,
                                                                  onNotConfigured,
                                                                  onFailure);
                }

                if (authenticationRequest.authorizationId.HasValue)
                {
                    return onInvalidToken("Session's authentication request cannot be re-used.");
                }

                return await await dataContext.CredentialMappings.LookupCredentialMappingAsync(method, subject, loginId,
                                                                                               async(authenticationId) =>
                {
                    return await await this.CreateSessionAsync(sessionId, authenticationId,
                                                               async(token, refreshToken) =>
                    {
                        await saveAuthRequest(authenticationId, token, extraParams);
                        return onLogin(sessionId, authenticationId,
                                       token, refreshToken, AuthenticationActions.signin, extraParams, authenticationRequest.redirect);
                    },
                                                               onNotConfigured.AsAsyncFunc());
                },
                                                                                               () => onInvalidToken("The token does not match a user in this system.").ToTask());
            },
                                                                             () => onInvalidToken("The token does not match an Authentication request")));
        }