public Task <IActionResult> Confirm(string id)
        {
            return(CallOperationWithAuthenticatedUser(async(sub, payload) =>
            {
                var pendingRequest = await _umaPendingRequestQueryRepository.FindByTicketIdentifierAndOwner(id, sub);
                if (pendingRequest == null)
                {
                    return this.BuildError(HttpStatusCode.Unauthorized, UMAErrorCodes.REQUEST_DENIED);
                }

                if (pendingRequest.Status != UMAPendingRequestStatus.TOBECONFIRMED)
                {
                    return this.BuildError(HttpStatusCode.BadRequest, ErrorCodes.INVALID_REQUEST, UMAErrorMessages.REQUEST_CANNOT_BE_CONFIRMED);
                }

                var resource = await _umaResourceQueryRepository.FindByIdentifier(pendingRequest.Resource.Id);
                foreach (var claimTokenFormat in _claimTokenFormats)
                {
                    resource.Permissions.Add(new UMAResourcePermission(Guid.NewGuid().ToString(), DateTime.UtcNow)
                    {
                        Claims = new List <UMAResourcePermissionClaim>
                        {
                            new UMAResourcePermissionClaim
                            {
                                Name = claimTokenFormat.GetSubjectName(),
                                Value = pendingRequest.Requester
                            }
                        },
                        Scopes = pendingRequest.Scopes.ToList()
                    });
                }

                pendingRequest.Confirm();
                _umaPendingRequestCommandRepository.Update(pendingRequest);
                _umaResourceCommandRepository.Update(resource);
                await _umaResourceCommandRepository.SaveChanges();
                await _umaPendingRequestCommandRepository.SaveChanges();
                return new NoContentResult();
            }));
        }
Beispiel #2
0
        public override async Task <IActionResult> Handle(HandlerContext context)
        {
            try
            {
                _umaTicketGrantTypeValidator.Validate(context);
                var oauthClient = await AuthenticateClient(context);

                context.SetClient(oauthClient);
                var ticket           = context.Request.Data.GetTicket();
                var claimTokenFormat = context.Request.Data.GetClaimTokenFormat();
                if (string.IsNullOrWhiteSpace(claimTokenFormat))
                {
                    claimTokenFormat = _umaHostOptions.DefaultClaimTokenFormat;
                }

                var scopes           = context.Request.Data.GetScopesFromAuthorizationRequest();
                var permissionTicket = await _umaPermissionTicketHelper.GetTicket(ticket);

                if (permissionTicket == null)
                {
                    throw new OAuthException(ErrorCodes.INVALID_GRANT, UMAErrorMessages.INVALID_TICKET);
                }

                ClaimTokenFormatFetcherResult claimTokenFormatFetcherResult = null;
                if (!string.IsNullOrWhiteSpace(claimTokenFormat))
                {
                    var claimTokenFormatFetcher = _claimTokenFormatFetchers.FirstOrDefault(c => c.Name == claimTokenFormat);
                    if (claimTokenFormatFetcher == null)
                    {
                        throw new OAuthException(ErrorCodes.INVALID_REQUEST, string.Format(UMAErrorMessages.BAD_TOKEN_FORMAT, claimTokenFormat));
                    }

                    claimTokenFormatFetcherResult = await claimTokenFormatFetcher.Fetch(context);
                }

                if (claimTokenFormatFetcherResult == null)
                {
                    return(BuildError(HttpStatusCode.Unauthorized, UMAErrorCodes.REQUEST_DENIED, UMAErrorMessages.REQUEST_DENIED));
                }

                var invalidScopes = permissionTicket.Records.Any(rec => !scopes.All(sc => rec.Scopes.Contains(sc)));
                if (invalidScopes)
                {
                    throw new OAuthException(ErrorCodes.INVALID_SCOPE, UMAErrorMessages.INVALID_SCOPE);
                }

                var umaResources = await _umaResourceQueryRepository.FindByIdentifiers(permissionTicket.Records.Select(r => r.ResourceId));

                var requiredClaims = new List <UMAResourcePermissionClaim>();
                foreach (var umaResource in umaResources)
                {
                    foreach (var permission in umaResource.Permissions)
                    {
                        if (permission.Scopes.Any(sc => scopes.Contains(sc)))
                        {
                            var unknownClaims = permission.Claims.Where(cl => !claimTokenFormatFetcherResult.Payload.Any(c => c.Key == cl.Name));
                            requiredClaims.AddRange(unknownClaims);
                        }
                    }
                }

                if (requiredClaims.Any())
                {
                    var needInfoResult = new JObject
                    {
                        { "need_info", new JObject
                          {
                              { UMATokenRequestParameters.Ticket, permissionTicket.Id },
                              { "required_claims", new JArray(requiredClaims.Select(rc => new JObject
                                    {
                                        { UMAResourcePermissionNames.ClaimTokenFormat, _umaHostOptions.DefaultClaimTokenFormat },
                                        { UMAResourcePermissionNames.ClaimType, rc.ClaimType },
                                        { UMAResourcePermissionNames.ClaimFriendlyName, rc.FriendlyName },
                                        { UMAResourcePermissionNames.ClaimName, rc.Name }
                                    })) },
                              { "redirect_uri", _umaHostOptions.OpenIdRedirectUrl }
                          } }
                    };
                    return(new ContentResult
                    {
                        Content = needInfoResult.ToString(),
                        ContentType = "application/json",
                        StatusCode = (int)HttpStatusCode.Unauthorized
                    });
                }

                var isNotAuthorized = umaResources.Any(ua => ua.Permissions.Where(p => p.Scopes.Any(sc => scopes.Contains(sc)))
                                                       .All(pr => pr.Claims.All(cl => claimTokenFormatFetcherResult.Payload.Any(c => c.Key == cl.Name && !c.Value.ToString().Equals(cl.Value, StringComparison.InvariantCultureIgnoreCase)))));
                if (isNotAuthorized)
                {
                    var pendingRequests = await _umaPendingRequestQueryRepository.FindByTicketIdentifier(permissionTicket.Id);

                    if (pendingRequests.Any())
                    {
                        return(BuildError(HttpStatusCode.Unauthorized, UMAErrorCodes.REQUEST_DENIED, UMAErrorMessages.REQUEST_DENIED));
                    }

                    foreach (var umaResource in umaResources)
                    {
                        var permissionTicketRecord = permissionTicket.Records.First(r => r.ResourceId == umaResource.Id);
                        var umaPendingRequest      = new UMAPendingRequest(permissionTicket.Id, umaResource.Subject, DateTime.UtcNow)
                        {
                            Requester = claimTokenFormatFetcherResult.Subject,
                            Scopes    = umaResource.Scopes,
                            Resource  = umaResource
                        };
                        _umaPendingRequestCommandRepository.Add(umaPendingRequest);
                    }

                    await _umaPendingRequestCommandRepository.SaveChanges();

                    return(new ContentResult
                    {
                        ContentType = "application/json",
                        StatusCode = (int)HttpStatusCode.Unauthorized,
                        Content = new JObject
                        {
                            { "request_submitted", new JObject
                              {
                                  { UMATokenRequestParameters.Ticket, permissionTicket.Id },
                                  { "interval", _umaHostOptions.RequestSubmittedInterval }
                              } }
                        }.ToString()
                    });
                }

                var jArr = new JArray();
                foreach (var permission in permissionTicket.Records)
                {
                    jArr.Add(new JObject()
                    {
                        { UMAPermissionNames.ResourceId, permission.ResourceId },
                        { UMAPermissionNames.ResourceScopes, new JArray(permission.Scopes) }
                    });
                }

                var result = BuildResult(context, scopes);
                foreach (var tokenBuilder in _tokenBuilders)
                {
                    await tokenBuilder.Build(scopes, context, new JObject
                    {
                        { "permissions", jArr }
                    }).ConfigureAwait(false);
                }

                _tokenProfiles.First(t => t.Profile == context.Client.PreferredTokenProfile).Enrich(context);
                foreach (var kvp in context.Response.Parameters)
                {
                    result.Add(kvp.Key, kvp.Value);
                }

                return(new OkObjectResult(result));
            }
            catch (OAuthException ex)
            {
                return(BuildError(HttpStatusCode.BadRequest, ex.Code, ex.Message));
            }
        }