Estoy creando una aplicación usando Spring con Oauth2 como back-end para dos aplicaciones (aplicación de proveedor y aplicación de consumidor). Tengo dos tipos diferentes de usuarios; Proveedores y consumidores, cada uno con su propia tabla de db. El problema al que me enfrento es que no puedo encontrar la manera de saber si la solicitud proviene de un proveedor o de un cliente, ya que cada uno estará en una tabla de base de datos diferente.
El nombre de usuario no es único entre las dos tablas. Entonces, un proveedor y un consumidor pueden tener el mismo nombre de usuario (y contraseña). Creo que cualquiera de las siguientes soluciones será suficiente, sin embargo, no puedo encontrar ninguna forma de implementar ninguna de ellas.
Si alguna de estas soluciones es posible, o si hay otra forma de lograr esto, házmelo saber. Cualquier ayuda es apreciada.
Editar - Solución
Siguiendo la respuesta a continuación, agregué otro cliente con una ID de cliente diferente, verifiqué la ID en UserDetailsService y luego decido qué base de datos usar. Aquí está el código:
public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException { UsernamePasswordAuthenticationToken authentication = (UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication(); User user = (User) authentication.getPrincipal(); String username = user.getUsername(); if (username.equals(OAuth2Configuration.provider_app)) // Load from provider db else if (username.equals(OAuth2Configuration.consumer_app)) // Load from consumer db else throw new UsernameNotFoundException("ClientID " + username + " not found."); } }; }UsernamePasswordAuthenticationToken se usa como /oauth/token está protegido con Basic Oauth usando la identificación y el secreto del cliente.
Creo que debería poder mirar dentro SecurityContextHolder.getContext().getAuthentication . Esta debería ser una instancia de OAuth2Authentication , desde la cual puede (después de enviar) llamar a getOAuth2Request() para obtener los detalles originales de Oauth2Request .
Con esta información, puede tener un solo UserDetailsService que puede delegar búsquedas en las tablas de base de datos correctas. Puede usar ámbitos o identificadores de recursos para ayudar a determinar qué tabla de base de datos usar.
Podrías usar la tercera opción. pero este no es un buen principio a seguir. puede enviar un parámetro personalizado en el punto final de oauth/token. se puede acceder mediante AutoWiring HttpServletRequest en userDetailsService.
Servicio de detalles de usuario
@Autowired private HttpServletRequest httpServletRequest; @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { try { String userType = httpServletRequest.getParameter("user_type"); LOGGER.info("Load user method \n Username : " + username + "\nuser_type : " + userType); if (userType == null) { throw new CustomOauthException("User type is required !"); } if (userType.equals(String.valueOf(MOBILE_USER))) { //get user.. } else if (userType.equals(String.valueOf(DRIVER))) { //get driver.. } else if (userType.equals(String.valueOf(ADMIN))) { //get admin } throw new CustomOauthException("User type is not valid !"); } catch (Exception e) { e.printStackTrace(); LOGGER.error("Exception : " + e.getMessage()); throw new CustomOauthException(e.getMessage()); } }