web security config
This commit is contained in:
parent
ba473d1dae
commit
239d16cfc4
96
src/main/java/cc/pulseapp/api/config/WebSecurityConfig.java
Normal file
96
src/main/java/cc/pulseapp/api/config/WebSecurityConfig.java
Normal file
@ -0,0 +1,96 @@
|
||||
package cc.pulseapp.api.config;
|
||||
|
||||
import cc.pulseapp.api.model.IGenericResponse;
|
||||
import cc.pulseapp.api.model.user.Session;
|
||||
import cc.pulseapp.api.repository.SessionRepository;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import lombok.NonNull;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.security.authentication.BadCredentialsException;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
|
||||
import org.springframework.security.config.http.SessionCreationPolicy;
|
||||
import org.springframework.security.web.SecurityFilterChain;
|
||||
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
||||
import org.springframework.security.web.authentication.preauth.AbstractPreAuthenticatedProcessingFilter;
|
||||
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
|
||||
|
||||
/**
|
||||
* @author Braydon
|
||||
*/
|
||||
@Configuration
|
||||
@EnableWebSecurity
|
||||
@Order(Ordered.HIGHEST_PRECEDENCE)
|
||||
public class WebSecurityConfig {
|
||||
/**
|
||||
* The session repository to use.
|
||||
*/
|
||||
@NonNull private final SessionRepository sessionRepository;
|
||||
|
||||
@Autowired
|
||||
public WebSecurityConfig(@NonNull SessionRepository sessionRepository) {
|
||||
this.sessionRepository = sessionRepository;
|
||||
}
|
||||
|
||||
@Bean @NonNull
|
||||
public SecurityFilterChain filterChain(@NonNull HttpSecurity http) throws Exception {
|
||||
SessionFilter filter = new SessionFilter();
|
||||
filter.setAuthenticationManager(authentication -> {
|
||||
Session authToken = (Session) authentication.getCredentials();
|
||||
if (authToken == null) { // No API key found
|
||||
throw new BadCredentialsException(Error.INVALID_ACCESS_TOKEN.name());
|
||||
}
|
||||
authentication.setAuthenticated(true); // Mark the session as authenticated
|
||||
return authentication;
|
||||
});
|
||||
return http.csrf(AbstractHttpConfigurer::disable) // Disable CSRF
|
||||
.sessionManagement(sessionManagement -> sessionManagement.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) // No sessions
|
||||
.formLogin(AbstractHttpConfigurer::disable) // Disable form logins
|
||||
.securityMatcher("/**") // Require auth for all routes
|
||||
.addFilterBefore(filter, UsernamePasswordAuthenticationFilter.class) // Add the auth token filter
|
||||
.authorizeHttpRequests(registry -> registry // Except for the following routes
|
||||
.requestMatchers(AntPathRequestMatcher.antMatcher("/")).permitAll()
|
||||
.requestMatchers(AntPathRequestMatcher.antMatcher("/error")).permitAll()
|
||||
.requestMatchers(AntPathRequestMatcher.antMatcher("/v*/auth/register")).permitAll()
|
||||
.requestMatchers(AntPathRequestMatcher.antMatcher("/v*/auth/login")).permitAll()
|
||||
.anyRequest().authenticated())
|
||||
.exceptionHandling(exceptionHandling -> exceptionHandling
|
||||
.authenticationEntryPoint((request, response, authException) -> { // Handle invalid access tokens
|
||||
response.sendError(HttpStatus.FORBIDDEN.value(), Error.INVALID_ACCESS_TOKEN.name());
|
||||
}))
|
||||
.build();
|
||||
}
|
||||
|
||||
private enum Error implements IGenericResponse {
|
||||
INVALID_ACCESS_TOKEN
|
||||
}
|
||||
|
||||
/**
|
||||
* The filter for authenticating
|
||||
* requests with an {@link Session}.
|
||||
*
|
||||
* @author Braydon
|
||||
*/
|
||||
public final class SessionFilter extends AbstractPreAuthenticatedProcessingFilter {
|
||||
@Override
|
||||
protected String getPreAuthenticatedPrincipal(@NonNull HttpServletRequest request) {
|
||||
return request.getHeader(HttpHeaders.AUTHORIZATION);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Session getPreAuthenticatedCredentials(@NonNull HttpServletRequest request) {
|
||||
String accessToken = getPreAuthenticatedPrincipal(request); // Get the provided access token
|
||||
if (accessToken == null || !accessToken.startsWith("Bearer ")) {
|
||||
return null;
|
||||
}
|
||||
return sessionRepository.findByAccessToken(accessToken.substring(7));
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user