SecurityRequirementsOperationFilter.cs 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  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. var requiresAuth = false;
  20. // Add all method scopes.
  21. foreach (var attribute in context.MethodInfo.GetCustomAttributes(true))
  22. {
  23. if (attribute is not AuthorizeAttribute authorizeAttribute)
  24. {
  25. continue;
  26. }
  27. requiresAuth = true;
  28. if (authorizeAttribute.Policy is not null
  29. && !requiredScopes.Contains(authorizeAttribute.Policy, StringComparer.Ordinal))
  30. {
  31. requiredScopes.Add(authorizeAttribute.Policy);
  32. }
  33. }
  34. // Add controller scopes if any.
  35. var controllerAttributes = context.MethodInfo.DeclaringType?.GetCustomAttributes(true);
  36. if (controllerAttributes is not null)
  37. {
  38. foreach (var attribute in controllerAttributes)
  39. {
  40. if (attribute is not AuthorizeAttribute authorizeAttribute)
  41. {
  42. continue;
  43. }
  44. requiresAuth = true;
  45. if (authorizeAttribute.Policy is not null
  46. && !requiredScopes.Contains(authorizeAttribute.Policy, StringComparer.Ordinal))
  47. {
  48. requiredScopes.Add(authorizeAttribute.Policy);
  49. }
  50. }
  51. }
  52. if (!requiresAuth)
  53. {
  54. return;
  55. }
  56. if (!operation.Responses.ContainsKey("401"))
  57. {
  58. operation.Responses.Add("401", new OpenApiResponse { Description = "Unauthorized" });
  59. }
  60. if (!operation.Responses.ContainsKey("403"))
  61. {
  62. operation.Responses.Add("403", new OpenApiResponse { Description = "Forbidden" });
  63. }
  64. var scheme = new OpenApiSecurityScheme
  65. {
  66. Reference = new OpenApiReference
  67. {
  68. Type = ReferenceType.SecurityScheme,
  69. Id = AuthenticationSchemes.CustomAuthentication
  70. }
  71. };
  72. operation.Security = new List<OpenApiSecurityRequirement>
  73. {
  74. new OpenApiSecurityRequirement
  75. {
  76. [scheme] = requiredScopes
  77. }
  78. };
  79. }
  80. }
  81. }