Я рад, что вы здесь читаете мой вопрос :)Spring Security - двойная аутентификация: X.509 для терминала, Логин форма для пользователя
Я занимаюсь разработкой веб-приложения, в весенне-ботинке за продажи магазин. Я создал систему входа в систему, которая использует formLogin() для авторизации пользователей (она работает как шарм), но я столкнулся с проблемой, когда обращается к обнаружению, в котором компьютер зарегистрирован пользователем. В качестве других фактов только определенные компьютеры должны иметь доступ к сайту и только одному пользователю. Кроме того, у меня есть (пользователь и терминал), реализованный в базе данных, связанной с JPA-данными Spring, и терминал имеет внешний ключ для пользователя (ноль, когда к нему никто не подключен).
После 3-дневного поиска в Google я пришел к выводу, что лучший способ реализовать это - установить сертификаты X.509 на каждом компьютере для взаимной аутентификации и использовать привилегию loginForm для пользователей. (У терминалов нет разрешений, но такая конфигурация, как «это должно работать с этим кассовым аппаратом» или «это должно использовать принтер квитанций»).
Таким образом, код-часть ... Это моя текущая конфигурация Spring Security:
@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
UserDetailsService userDetailsService;
@Autowired
DataSource dataSource;
@Autowired
public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService);
auth.authenticationProvider(authenticationProvider());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/", "/index", "/static/**", "/login", "/catalogo/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.loginProcessingUrl("/login")
.usernameParameter("username")
.passwordParameter("password")
.and()
.logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.invalidateHttpSession(true)
.clearAuthentication(true)
.and()
.rememberMe()
.rememberMeParameter("remember-me")
.tokenRepository(persistentTokenRepository())
.tokenValiditySeconds(86400).and()
.csrf()
.and()
.exceptionHandling().accessDeniedPage("/Access_Denied");
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public DaoAuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
authenticationProvider.setUserDetailsService(userDetailsService);
authenticationProvider.setPasswordEncoder(passwordEncoder());
return authenticationProvider;
}
@Bean
public AuthenticationTrustResolver getAuthenticationTrustResolver() {
return new AuthenticationTrustResolverImpl();
}
@Bean
public PersistentTokenRepository persistentTokenRepository() {
JdbcTokenRepositoryImpl tokenRepositoryImpl = new JdbcTokenRepositoryImpl();
tokenRepositoryImpl.setDataSource(dataSource);
return tokenRepositoryImpl;
}
}
И это мой UserDetailService:
@Service("customUserDetailsService")
public class CustomUserDetailsService implements UserDetailsService {
private static final Logger logger = LoggerFactory.getLogger(CustomUserDetailsService.class);
// This is my user model service in Spring-data JPA, I have one too for terminals
@Autowired
private SecurityUserService securityUserService;
@Transactional(readOnly=true)
public UserDetails loadUserByUsername(String username)
throws UsernameNotFoundException {
SecurityUser user = securityUserService.findByUsername(username);
logger.info("User : {}", user);
if(user==null){
logger.info("User not found");
throw new UsernameNotFoundException("Username not found");
}
return new org.springframework.security.core.userdetails.User(
user.getUsername(), user.getPassword(), true, true, true,
true, getGrantedAuthorities(getPermissions(user)));
}
private List<GrantedAuthority> getGrantedAuthorities(List<String> permisos) {
List<GrantedAuthority> authorities = new ArrayList<>();
for (String permiso : permisos) {
authorities.add(new SimpleGrantedAuthority(permiso));
}
return authorities;
}
private List<String> getPermissions(SecurityUser user) {
List<String> privileges = new ArrayList<>();
List<SecurityPermission> collection = new ArrayList<>();
for (SecurityRole role : user.getRoles()) {
collection.addAll(role.getPermissions());
}
collection.addAll(user.getPermissions());
for (SecurityPermission item : collection) {
privileges.add(item.getName());
}
return privileges;
}
}
В основном теперь я должен добавить X .509 аутентификация сертификата. Я сделал это без формы входа и работал хорошо, но я не знаю, как обращаться с ними вместе.
Благодарим за помощь.
PS: если вы думаете, что у вас есть еще одно возможное решение этой проблемы, не бойтесь оставлять его