DeviceClientAuthenticationProvider.java 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. /*
  2. * Copyright 2020-2023 the original author or authors.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * https://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package sample.authentication;
  17. import org.apache.commons.logging.Log;
  18. import org.apache.commons.logging.LogFactory;
  19. import sample.web.authentication.DeviceClientAuthenticationConverter;
  20. import org.springframework.security.authentication.AuthenticationProvider;
  21. import org.springframework.security.core.Authentication;
  22. import org.springframework.security.core.AuthenticationException;
  23. import org.springframework.security.oauth2.core.ClientAuthenticationMethod;
  24. import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
  25. import org.springframework.security.oauth2.core.OAuth2Error;
  26. import org.springframework.security.oauth2.core.OAuth2ErrorCodes;
  27. import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
  28. import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
  29. import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository;
  30. import org.springframework.security.oauth2.server.authorization.web.OAuth2ClientAuthenticationFilter;
  31. import org.springframework.util.Assert;
  32. /**
  33. * @author Joe Grandja
  34. * @author Steve Riesenberg
  35. * @since 1.1
  36. * @see DeviceClientAuthenticationToken
  37. * @see DeviceClientAuthenticationConverter
  38. * @see OAuth2ClientAuthenticationFilter
  39. */
  40. public final class DeviceClientAuthenticationProvider implements AuthenticationProvider {
  41. private static final String ERROR_URI = "https://datatracker.ietf.org/doc/html/rfc6749#section-3.2.1";
  42. private final Log logger = LogFactory.getLog(getClass());
  43. private final RegisteredClientRepository registeredClientRepository;
  44. public DeviceClientAuthenticationProvider(RegisteredClientRepository registeredClientRepository) {
  45. Assert.notNull(registeredClientRepository, "registeredClientRepository cannot be null");
  46. this.registeredClientRepository = registeredClientRepository;
  47. }
  48. @Override
  49. public Authentication authenticate(Authentication authentication) throws AuthenticationException {
  50. DeviceClientAuthenticationToken deviceClientAuthentication =
  51. (DeviceClientAuthenticationToken) authentication;
  52. if (!ClientAuthenticationMethod.NONE.equals(deviceClientAuthentication.getClientAuthenticationMethod())) {
  53. return null;
  54. }
  55. String clientId = deviceClientAuthentication.getPrincipal().toString();
  56. RegisteredClient registeredClient = this.registeredClientRepository.findByClientId(clientId);
  57. if (registeredClient == null) {
  58. throwInvalidClient(OAuth2ParameterNames.CLIENT_ID);
  59. }
  60. if (this.logger.isTraceEnabled()) {
  61. this.logger.trace("Retrieved registered client");
  62. }
  63. if (!registeredClient.getClientAuthenticationMethods().contains(
  64. deviceClientAuthentication.getClientAuthenticationMethod())) {
  65. throwInvalidClient("authentication_method");
  66. }
  67. if (this.logger.isTraceEnabled()) {
  68. this.logger.trace("Validated device client authentication parameters");
  69. }
  70. if (this.logger.isTraceEnabled()) {
  71. this.logger.trace("Authenticated device client");
  72. }
  73. return new DeviceClientAuthenticationToken(registeredClient,
  74. deviceClientAuthentication.getClientAuthenticationMethod(), null);
  75. }
  76. @Override
  77. public boolean supports(Class<?> authentication) {
  78. return DeviceClientAuthenticationToken.class.isAssignableFrom(authentication);
  79. }
  80. private static void throwInvalidClient(String parameterName) {
  81. OAuth2Error error = new OAuth2Error(
  82. OAuth2ErrorCodes.INVALID_CLIENT,
  83. "Device client authentication failed: " + parameterName,
  84. ERROR_URI
  85. );
  86. throw new OAuth2AuthenticationException(error);
  87. }
  88. }