具有Spring Security和Java配置的自定义validation管理器

我正在使用Spring Security与SpringMVC创建一个Web应用程序(为了清楚起见,我将其称为WebApp),它与现有应用程序相对应(我将其称为BackendApp)。

我想将身份validation职责委派给BackendApp(这样我就不需要同步这两个应用程序)。

为了实现这一点,我希望WebApp(运行Spring安全性)通过REST与用户在表单中提供的用户名和密码与BackendApp进行通信,并根据BackendApp的响应是200 OK还是401 Unauthorized进行身份validation。

我知道我需要编写一个自定义的身份validation管理器来执行此操作,但我是一个非常新的spring,无法找到有关如何实现它的任何信息。

我相信我需要做这样的事情:

public class CustomAuthenticationManager implements AuthenticationManager{ @Override public Authentication authenticate(Authentication authentication) throws AuthenticationException { String username = authentication.getName(); String pw = authentication.getCredentials().toString(); // Code to make rest call here and check for OK or Unauthorised. // What do I return? } } 

如果成功,我是否设置authentication.setAuthenticated(true),否则设置为false,那就是它?

编写完成后,如何使用java配置文件配置spring security以使用此身份validation管理器?

在此先感谢您的任何帮助。

看看下面的示例。 您必须返回UsernamePasswordAuthenticationToken。 它包含主体和GrantedAuthorities。 希望我能帮忙:)

 public Authentication authenticate(Authentication authentication) throws AuthenticationException { String username = authentication.getPrincipal() + ""; String password = authentication.getCredentials() + ""; User user = userRepo.findOne(username); if (user == null) { throw new BadCredentialsException("1000"); } if (user.isDisabled()) { throw new DisabledException("1001"); } if (!encoder.matches(password, user.getPassword())) { throw new BadCredentialsException("1000"); } List userRights = rightRepo.getUserRights(username); return new UsernamePasswordAuthenticationToken(username, password, userRights.stream().map(x -> new SimpleGrantedAuthority(x.getName())).collect(Collectors.toList())); } 

PS:userRepo和rightRepo是访问我的自定义User-DB的Spring-Data-JPA存储库

SpringSecurity JavaConfig:

 @Configuration @EnableWebMvcSecurity public class MySecurityConfiguration extends WebSecurityConfigurerAdapter { public MySecurityConfiguration() { super(false); } @Override protected AuthenticationManager authenticationManager() throws Exception { return new ProviderManager(Arrays.asList((AuthenticationProvider) new AuthProvider())); } } 

最简单的:

 @Override public Authentication authenticate(Authentication auth) throws AuthenticationException { String username = auth.getName(); String password = auth.getCredentials().toString(); // to add more logic List grantedAuths = new ArrayList<>(); grantedAuths.add(new SimpleGrantedAuthority("ROLE_USER")); return new UsernamePasswordAuthenticationToken(username, password, grantedAuths); } 

首先,您必须配置Spring安全性以使用自定义AuthenticationProvider。 因此,在spring-security.xml(或等效的配置文件)中,您必须定义哪个类正在实现此function。 例如:

       

其次,您必须在示例中实现AuthenticationProvider。 特别是方法validation(validation身份validation),您的rest呼叫必须在其中。 例如:

 public Authentication authenticate(Authentication authentication) throws AuthenticationException { User user = null; try { //use a rest service to find the user. //Spring security provides user login name in authentication.getPrincipal() user = userRestService.loadUserByUsername(authentication.getPrincipal().toString()); } catch (Exception e) { log.error("Error loading user, not found: " + e.getMessage(), e); } if (user == null) { throw new UsernameNotFoundException(String.format("Invalid credentials", authentication.getPrincipal())); } else if (!user.isEnabled()) { throw new UsernameNotFoundException(String.format("Not found enabled user for username ", user.getUsername())); } //check user password stored in authentication.getCredentials() against stored password hash if (StringUtils.isBlank(authentication.getCredentials().toString()) || !passwordEncoder.isPasswordValid(user.getPasswordHash(), authentication.getCredentials().toString()) { throw new BadCredentialsException("Invalid credentials"); } //doLogin makes whatever is necesary when login is made (put info in session, load other data etc..) return doLogin(user); } 

我的解决方案几乎与第一个答案相同:

1)您需要一个实现身份validation提供程序的类

 @Service @Configurable public class CustomAuthenticationProvider implements AuthenticationProvider { @Override public Authentication authenticate(Authentication authentication) throws AuthenticationException { // Your code of custom Authentication } } 

2)与第一个答案相反,如果您只有此自定义提供程序,则无需在WebSecurityConfiguration中使用以下代码。

 @Override protected AuthenticationManager authenticationManager() throws Exception { return new ProviderManager(Arrays.asList((AuthenticationProvider) new AuthProvider())); } 

问题是Spring会查找可用的提供程序,如果没有找到其他内容,则使用默认值。 但是,当您拥有AuthenticationProvider的实现时 – 将使用您的实现。