Added explicitly defined endpoint security.
This commit is contained in:
parent
f8dcfc8843
commit
4293ddb157
|
@ -3,6 +3,7 @@ package nl.andrewlalis.gymboard_api.config;
|
|||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
|
@ -38,7 +39,22 @@ public class SecurityConfig {
|
|||
.csrf().disable()
|
||||
.cors().and()
|
||||
.addFilterBefore(tokenAuthenticationFilter, UsernamePasswordAuthenticationFilter.class)
|
||||
.authorizeHttpRequests().anyRequest().permitAll();
|
||||
.authorizeHttpRequests()
|
||||
.requestMatchers(// Allow the following GET endpoints to be public.
|
||||
HttpMethod.GET,
|
||||
"/exercises",
|
||||
"/leaderboards",
|
||||
"/gyms/**",
|
||||
"/submissions/**"
|
||||
).permitAll()
|
||||
.requestMatchers(// Allow the following POST endpoints to be public.
|
||||
HttpMethod.POST,
|
||||
"/gyms/submissions",
|
||||
"/gyms/submissions/upload",
|
||||
"/auth/token"
|
||||
).permitAll()
|
||||
// Everything else must be authenticated, just to be safe.
|
||||
.anyRequest().authenticated();
|
||||
return http.build();
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
|||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
|
||||
@Configuration
|
||||
public class SecurityComponents {
|
||||
public class WebComponents {
|
||||
@Bean
|
||||
public PasswordEncoder passwordEncoder() {
|
||||
return new BCryptPasswordEncoder(10);
|
|
@ -5,7 +5,7 @@ import nl.andrewlalis.gymboard_api.controller.dto.TokenResponse;
|
|||
import nl.andrewlalis.gymboard_api.controller.dto.UserResponse;
|
||||
import nl.andrewlalis.gymboard_api.model.auth.User;
|
||||
import nl.andrewlalis.gymboard_api.service.auth.TokenService;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.annotation.AuthenticationPrincipal;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
|
@ -20,13 +20,38 @@ public class AuthController {
|
|||
this.tokenService = tokenService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Endpoint for obtaining a new access token for a user to access certain
|
||||
* parts of the application. <strong>This is a public endpoint.</strong> If
|
||||
* a token is successfully obtained, it should be provided to all subsequent
|
||||
* requests as an Authorization "Bearer" token.
|
||||
* @param credentials The credentials.
|
||||
* @return The token the client should use.
|
||||
*/
|
||||
@PostMapping(path = "/auth/token")
|
||||
public TokenResponse getToken(@RequestBody TokenCredentials credentials) {
|
||||
return tokenService.generateAccessToken(credentials);
|
||||
}
|
||||
|
||||
/**
|
||||
* Endpoint that can be used by an authenticated user to fetch a new access
|
||||
* token using their current one; useful for staying logged in beyond the
|
||||
* duration of the initial token's expiration.
|
||||
* @param auth The current authentication.
|
||||
* @return The new token the client should use.
|
||||
*/
|
||||
@GetMapping(path = "/auth/token")
|
||||
public TokenResponse getUpdatedToken(Authentication auth) {
|
||||
return tokenService.regenerateAccessToken(auth);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets information about the user, as determined by the provided access
|
||||
* token.
|
||||
* @param user The user that requested information.
|
||||
* @return The user data.
|
||||
*/
|
||||
@GetMapping(path = "/auth/me")
|
||||
@PreAuthorize("isAuthenticated()")
|
||||
public UserResponse getMyUser(@AuthenticationPrincipal User user) {
|
||||
return new UserResponse(user);
|
||||
}
|
||||
|
|
|
@ -8,11 +8,13 @@ import nl.andrewlalis.gymboard_api.controller.dto.TokenCredentials;
|
|||
import nl.andrewlalis.gymboard_api.controller.dto.TokenResponse;
|
||||
import nl.andrewlalis.gymboard_api.dao.auth.UserRepository;
|
||||
import nl.andrewlalis.gymboard_api.model.auth.Role;
|
||||
import nl.andrewlalis.gymboard_api.model.auth.TokenAuthentication;
|
||||
import nl.andrewlalis.gymboard_api.model.auth.User;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.server.ResponseStatusException;
|
||||
|
@ -67,6 +69,22 @@ public class TokenService {
|
|||
if (!passwordEncoder.matches(credentials.password(), user.getPasswordHash())) {
|
||||
throw new ResponseStatusException(HttpStatus.UNAUTHORIZED);
|
||||
}
|
||||
if (!user.isActivated()) {
|
||||
throw new ResponseStatusException(HttpStatus.UNAUTHORIZED);
|
||||
}
|
||||
String token = generateAccessToken(user);
|
||||
return new TokenResponse(token);
|
||||
}
|
||||
|
||||
public TokenResponse regenerateAccessToken(Authentication auth) {
|
||||
if (!(auth instanceof TokenAuthentication tokenAuth)) {
|
||||
throw new ResponseStatusException(HttpStatus.UNAUTHORIZED);
|
||||
}
|
||||
User user = userRepository.findByIdWithRoles(tokenAuth.user().getId())
|
||||
.orElseThrow(() -> new ResponseStatusException(HttpStatus.UNAUTHORIZED));
|
||||
if (!user.isActivated()) {
|
||||
throw new ResponseStatusException(HttpStatus.UNAUTHORIZED);
|
||||
}
|
||||
String token = generateAccessToken(user);
|
||||
return new TokenResponse(token);
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
Use this page to test new functionality, before adding it to the main
|
||||
app. This page should be hidden on production.
|
||||
</p>
|
||||
<div class="row" style="border: 3px solid red">
|
||||
<div style="border: 3px solid red">
|
||||
<h4>Auth Test</h4>
|
||||
<q-btn
|
||||
label="Do auth"
|
||||
|
|
Loading…
Reference in New Issue