Я работаю над проектом Spring Boot, который должен отслеживать пользователей. Зарегистрируйте их и, конечно же, зарегистрируйте их, и если они долго не будут ничего делать, истек срок их сеанса, а это означает, что на веб-сайте, если он слишком журнальный, вам нужно будет войти снова. Это реализовано, и на сервере есть множество асин c запросов для ускорения работы. Мой вопрос очень прост, разрешает ли Spring Security многопользовательскую аутентификацию? Это значит, что на разных машинах одновременно могут войти в систему и общаться с сервером 50 пользователей?
Это то, что я сделал до сих пор:
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserService service;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/login", "/register").permitAll().anyRequest().authenticated();
http.addFilterBefore(new AuthenticationFilter("/login", super.authenticationManagerBean()), BasicAuthenticationFilter.class)
.addFilterBefore(new RegistrationFilter("/register", service), BasicAuthenticationFilter.class)
.addFilterBefore(new DefaultAuthenticationToken(), BasicAuthenticationFilter.class);
}
private static void addResponseToken(Authentication auth, HttpServletResponse response) {
Map<String, Object> claims = new HashMap<>();
String token = Jwts.builder().setClaims(claims).setSubject("").setIssuedAt(new Date(System.currentTimeMillis())).setExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 60 * 10)).signWith(SignatureAlgorithm.HS256, "").compact();
if(response.containsHeader("Authorization"))
response.setHeader("Authorization", token);
else
response.addHeader("Authorization", token);
}
private static class AuthenticationFilter extends AbstractAuthenticationProcessingFilter {
private final AuthenticationManager manager;
protected AuthenticationFilter(String defaultFilterProcessesUrl, AuthenticationManager auth) {
super(defaultFilterProcessesUrl);
this.manager = auth;
}
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
throws AuthenticationException, IOException {
CredentialsDTO user = new Gson().fromJson(new InputStreamReader(request.getInputStream()), CredentialsDTO.class);
//ObjectMapper().readValue(request.getInputStream(), UserDTO.class);
Authentication auth = manager.authenticate(new UsernamePasswordAuthenticationToken(user.getEmail(), user.getPassword()));
if(auth.isAuthenticated()) {
SecurityContextHolder.getContext().setAuthentication(auth);
return auth;
}
return null;
}
@Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response,
FilterChain chain, Authentication authResult) throws IOException, ServletException {
addResponseToken(authResult, response);
}
}
private static class RegistrationFilter extends AbstractAuthenticationProcessingFilter {
private final UserService service;
protected RegistrationFilter(String defaultFilterProcessesUrl, UserService service) {
super(defaultFilterProcessesUrl);
this.service = service;
}
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
throws AuthenticationException, IOException {
UserDTO user = new Gson().fromJson(new InputStreamReader(request.getInputStream()), UserDTO.class);
//service.addUser(Transposers.toDAO(user));
Authentication auth = new AuthToken(user.getEmail(), Arrays.asList(user.getRoles()));
SecurityContextHolder.getContext().setAuthentication(auth);
return auth;
}
@Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response,
FilterChain chain, Authentication authResult) throws IOException, ServletException {
addResponseToken(authResult, response);
}
@Override
protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response,
AuthenticationException failed) throws IOException, ServletException {
super.unsuccessfulAuthentication(request, response, failed);
}
}
private static class DefaultAuthenticationToken extends GenericFilterBean {
@Override
@SuppressWarnings("unchecked")
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
String input = ((HttpServletRequest) request).getHeader("Authentication");
if(input != null && input.startsWith("Bearer ")) {
String token = input.substring(7);
Map<String, Object> claims = Jwts.parser().setSigningKey("").parseClaimsJws(token).getBody();
int expiration = (int) claims.get("exp");
if(expiration < System.currentTimeMillis() / 1000)
((HttpServletResponse) request).sendError(HttpServletResponse.SC_UNAUTHORIZED);
else {
List<String> roles = ((List<String>) claims.get("roles"));
Authentication auth = new AuthToken(claims.get("username"), roles);
SecurityContextHolder.getContext().setAuthentication(auth);
addResponseToken(auth, (HttpServletResponse) response);
chain.doFilter(request, response);
}
} else
((HttpServletResponse) response).sendError(HttpServletResponse.SC_UNAUTHORIZED);
}
}
private static class AuthToken implements Authentication {
private static final long serialVersionUID = 8528618298834061551L;
private List<GrantedAuthority> auths;
private String email;
public AuthToken(Object email, List<String> asList) {
this.email = (String) email;
this.auths = new ArrayList<>(asList.size());
asList.forEach((s) -> auths.add(new SimpleGrantedAuthority(s)));
}
@Override
public String getName() {
return email;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return auths;
}
@Override
public Object getCredentials() {
return null;
}
@Override
public Object getDetails() {
return email;
}
@Override
public Object getPrincipal() {
return this;
}
@Override
public boolean isAuthenticated() {
return true;
}
@Override
public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException {}
}
}