SecurityRequirementsOperationFilter.cs 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using Jellyfin.Api.Constants;
  5. using Microsoft.AspNetCore.Authorization;
  6. using Microsoft.OpenApi.Models;
  7. using Swashbuckle.AspNetCore.SwaggerGen;
  8. namespace Jellyfin.Server.Filters
  9. {
  10. /// <summary>
  11. /// Security requirement operation filter.
  12. /// </summary>
  13. public class SecurityRequirementsOperationFilter : IOperationFilter
  14. {
  15. /// <inheritdoc />
  16. public void Apply(OpenApiOperation operation, OperationFilterContext context)
  17. {
  18. var requiredScopes = new List<string>();
  19. // Add all method scopes.
  20. foreach (var attribute in context.MethodInfo.GetCustomAttributes(true))
  21. {
  22. if (attribute is AuthorizeAttribute authorizeAttribute
  23. && authorizeAttribute.Policy != null
  24. && !requiredScopes.Contains(authorizeAttribute.Policy, StringComparer.Ordinal))
  25. {
  26. requiredScopes.Add(authorizeAttribute.Policy);
  27. }
  28. }
  29. // Add controller scopes if any.
  30. var controllerAttributes = context.MethodInfo.DeclaringType?.GetCustomAttributes(true);
  31. if (controllerAttributes != null)
  32. {
  33. foreach (var attribute in controllerAttributes)
  34. {
  35. if (attribute is AuthorizeAttribute authorizeAttribute
  36. && authorizeAttribute.Policy != null
  37. && !requiredScopes.Contains(authorizeAttribute.Policy, StringComparer.Ordinal))
  38. {
  39. requiredScopes.Add(authorizeAttribute.Policy);
  40. }
  41. }
  42. }
  43. if (requiredScopes.Count != 0)
  44. {
  45. if (!operation.Responses.ContainsKey("401"))
  46. {
  47. operation.Responses.Add("401", new OpenApiResponse { Description = "Unauthorized" });
  48. }
  49. if (!operation.Responses.ContainsKey("403"))
  50. {
  51. operation.Responses.Add("403", new OpenApiResponse { Description = "Forbidden" });
  52. }
  53. var scheme = new OpenApiSecurityScheme
  54. {
  55. Reference = new OpenApiReference
  56. {
  57. Type = ReferenceType.SecurityScheme,
  58. Id = AuthenticationSchemes.CustomAuthentication
  59. }
  60. };
  61. operation.Security = new List<OpenApiSecurityRequirement>
  62. {
  63. new OpenApiSecurityRequirement
  64. {
  65. [scheme] = requiredScopes
  66. }
  67. };
  68. }
  69. }
  70. }
  71. }