Springboot аутентификация с дополнительным настраиваемым параметром
Я пытаюсь использовать весеннюю загрузку в моем приложении. Мне нужно дать доступ как продавцам, так и клиентам. Каждый из них сопоставлен с различными сущностями и, в свою очередь, использует разные репозитории.
Как моя реализация UserDetailServive может использовать другой репозиторий в зависимости от настраиваемого параметра формы?
<form th:action="@{/login}" method="post">
<div>
<label>User Name: <input type="text" name="username"/></label>
<label>Password: <input type="password" name="password"/></label>
<label>User type: <input type="radio" name="userType" value="customer"/>
<input type="radio" name="userType" value="salesMen"/></label>
</div>
<div><input type="submit" value="Login"/></div>
</form>
@Service
public class UserDetailServiceImpl implements UserDetailsService {
@Autowired
SalesMenRepository salesMenRepository;
@Autowired
CustomersRepository customersRepository;
@Override
public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {
// How can I get userType parameter ????
if ("salesMen".equals(userType)) {
Optional<SalesMan> salesMan = salesMenRepository.findById(userName);
if (!salesMan.isPresent()) {
throw new UsernameNotFoundException(userName);
}
return new UserDetailsImp(salesMan.get());
} else {
Optional<Customer> customer = customersRepository.findById(userName);
if (!customer.isPresent()) {
throw new UsernameNotFoundException(userName);
}
return new UserDetailsImp(customer.get());
}
}
}
1 ответ
Ты можешь присоединиться userName
с userType
любым символом, например двоеточием:userName:userType
, а в методе loadUserByUsername вы разделяете и получаете егоString[] parts = userName.split(":");
Но когда вы присоединяете пользовательский параметр к userName, вы должны настроить фильтр аутентификации. В моем случае я добавляю новый пользовательский параметр с именем dmBhxhId
, Я создаю CustomUser:
public class CustomUser extends User {
private Long dmBhxhId;
public Long getDmBhxhId() {
return dmBhxhId;
}
public void setDmBhxhId(Long dmBhxhId) {
this.dmBhxhId = dmBhxhId;
}
public CustomUser(String username, String password, Collection<? extends GrantedAuthority> authorities,
Long dmBhxhId) {
super(username, password, authorities);
this.dmBhxhId = dmBhxhId;
}
public CustomUser(String username, String password, Collection<? extends GrantedAuthority> authorities) {
super(username, password, authorities);
}
}
И я пользовательский фильтр аутентификации
public class CustomAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
private String extraParameter = "extra";
private String delimiter = ":";
/**
* Given an {@link HttpServletRequest}, this method extracts the username
* and the extra input values and returns a combined username string of
* those values separated by the delimiter string.
*
* @param request
* The {@link HttpServletRequest} containing the HTTP request
* variables from which the username client domain values can be
* extracted
*/
@Override
protected String obtainUsername(HttpServletRequest request) {
String username = request.getParameter(getUsernameParameter());
String extraInput = request.getParameter(getExtraParameter());
Map<String, String[]> map = request.getParameterMap();
String combinedUsername = username + getDelimiter() + extraInput;
return combinedUsername;
}
/**
* @return The parameter name which will be used to obtain the extra input
* from the login request
*/
public String getExtraParameter() {
return this.extraParameter;
}
/**
* @param extraParameter
* The parameter name which will be used to obtain the extra
* input from the login request
*/
public void setExtraParameter(String extraParameter) {
this.extraParameter = extraParameter;
}
/**
* @return The delimiter string used to separate the username and extra
* input values in the string returned by
* <code>obtainUsername()</code>
*/
public String getDelimiter() {
return this.delimiter;
}
/**
* @param delimiter
* The delimiter string used to separate the username and extra
* input values in the string returned by
* <code>obtainUsername()</code>
*/
public void setDelimiter(String delimiter) {
this.delimiter = delimiter;
}
}
В файле SecurityConfiguration я запускаю CustomAuthenticationFilter
@Bean
public CustomAuthenticationFilter customAuthenticationFilter() throws Exception {
CustomAuthenticationFilter bcsAuthFilter = new CustomAuthenticationFilter();
bcsAuthFilter.setAuthenticationManager(authenticationManager());
bcsAuthFilter.setAuthenticationFailureHandler(ajaxAuthenticationFailureHandler);
bcsAuthFilter.setAuthenticationSuccessHandler(ajaxAuthenticationSuccessHandler);
bcsAuthFilter.setFilterProcessesUrl("/api/authentication");
bcsAuthFilter.setPostOnly(true);
bcsAuthFilter.setExtraParameter("dm_bhxh_id");
bcsAuthFilter.setUsernameParameter("j_username");
bcsAuthFilter.setPasswordParameter("j_password");
return bcsAuthFilter;
}
И вызвать его в методе настройки
.addFilterBefore(bcsAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
выглядит как
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf()
.ignoringAntMatchers("/websocket/**").ignoringAntMatchers("/api/public/odts/**")
.and()
.addFilterBefore(bcsAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
.addFilterAfter(new CsrfCookieGeneratorFilter(), CsrfFilter.class)
.exceptionHandling()
.authenticationEntryPoint(authenticationEntryPoint)
....
Готово, надеюсь помочь вам! Извините, мой английский не очень хорош.