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(); })); }
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)); } }