我正在使用Spring创建一个应用程序,将Oauth2作为两个应用程序(提供者应用程序和消费者应用程序)的后端。我有两种不同类型的用户;提供者和消费者,每个人都有自己的数据库表。 我面临的问题是我无法找到一种方法来了解请求是来自提供者还是客户,因为每个请求都在不同的数据库表中。
两个表之间的用户名不唯一。因此,提供者和消费者可以拥有相同的用户名(和密码)。 我认为以下任何解决方案都足够了,但是,我找不到任何方法来实现它们。
如果可以使用这些解决方案,或者有其他方法可以解决此问题,请告知我们。 任何帮助表示赞赏。
修改 - 解决方案
根据下面的答案,我添加了另一个具有不同客户端ID的客户端,检查UserDetailsService中的id,然后决定使用哪个数据库。这是代码:
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用作/ oauth / token使用客户端ID和密钥使用Basic Oauth进行保护。
答案 0 :(得分:1)
我认为你应该能够查看SecurityContextHolder.getContext().getAuthentication
。
这应该是OAuth2Authentication
的一个实例,您可以(在投射后)调用getOAuth2Request()来获取原始Oauth2Request详细信息。
使用此信息,您可以拥有一个UserDetailsService
,可以将查找委派给正确的数据库表。您可以使用范围或resourceIds来帮助确定要使用的db表。
答案 1 :(得分:0)
您可以使用第三个选项。但这不是要遵循的好原则。您可以在oauth / token端点中发送自定义参数。可以通过userDetailsService中的AutoWiring HttpServletRequest访问它。
UserDetailsService
@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());
}
}