diff --git a/quartz-manager-api/.gitignore b/quartz-manager-api/.gitignore index 233a70f..b889765 100644 --- a/quartz-manager-api/.gitignore +++ b/quartz-manager-api/.gitignore @@ -7,3 +7,5 @@ /mvnw /mvnw.cmd /.classpath +/.idea/ +/quartz-manager.iml diff --git a/quartz-manager-api/src/main/java/it/fabioformosa/quartzmanager/configuration/helpers/impl/UsernamePasswordFiterLoginConfig.java b/quartz-manager-api/src/main/java/it/fabioformosa/quartzmanager/configuration/helpers/impl/UsernamePasswordFiterLoginConfig.java index 4d26310..1a89bff 100644 --- a/quartz-manager-api/src/main/java/it/fabioformosa/quartzmanager/configuration/helpers/impl/UsernamePasswordFiterLoginConfig.java +++ b/quartz-manager-api/src/main/java/it/fabioformosa/quartzmanager/configuration/helpers/impl/UsernamePasswordFiterLoginConfig.java @@ -1,5 +1,6 @@ package it.fabioformosa.quartzmanager.configuration.helpers.impl; +import it.fabioformosa.quartzmanager.security.auth.JwtAuthenticationSuccessHandler; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.http.HttpMethod; @@ -23,8 +24,11 @@ public class UsernamePasswordFiterLoginConfig implements LoginConfig { @Autowired private JwtTokenHelper jwtTokenHelper; + @Autowired + private JwtAuthenticationSuccessHandler jwtAuthenticationSuccessHandler; + public GenericFilterBean authenticationProcessingFilter(AuthenticationManager authenticationManager) throws Exception { - JwtAuthenticationFilter authenticationProcessingFilter = new JwtAuthenticationFilter(authenticationManager, jwtTokenHelper); + JwtAuthenticationFilter authenticationProcessingFilter = new JwtAuthenticationFilter(authenticationManager, jwtTokenHelper, jwtAuthenticationSuccessHandler); authenticationProcessingFilter.setRequiresAuthenticationRequestMatcher(new RegexRequestMatcher(API_LOGIN, HttpMethod.POST.name(), false)); return authenticationProcessingFilter; } diff --git a/quartz-manager-api/src/main/java/it/fabioformosa/quartzmanager/security/auth/AuthenticationSuccessHandler.java b/quartz-manager-api/src/main/java/it/fabioformosa/quartzmanager/security/auth/AuthenticationSuccessHandler.java index df6d282..46a2e32 100644 --- a/quartz-manager-api/src/main/java/it/fabioformosa/quartzmanager/security/auth/AuthenticationSuccessHandler.java +++ b/quartz-manager-api/src/main/java/it/fabioformosa/quartzmanager/security/auth/AuthenticationSuccessHandler.java @@ -3,66 +3,27 @@ package it.fabioformosa.quartzmanager.security.auth; import java.io.IOException; import javax.servlet.ServletException; -import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.security.core.Authentication; -import org.springframework.security.core.userdetails.User; import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler; import org.springframework.stereotype.Component; -import com.fasterxml.jackson.databind.ObjectMapper; - -import it.fabioformosa.quartzmanager.security.JwtTokenHelper; -import it.fabioformosa.quartzmanager.security.model.UserTokenState; - @Component @ConditionalOnProperty(prefix = "quartz-manager.security.login-model", name = "form-login-enabled", havingValue = "true", matchIfMissing = true) public class AuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler { - @Value("${quartz-manager.security.jwt.expiration-in-sec}") - private int EXPIRES_IN_SEC; - - @Value("${quartz-manager.security.jwt.cookie}") - private String TOKEN_COOKIE; - @Autowired - JwtTokenHelper tokenHelper; - // - @Autowired - ObjectMapper objectMapper; + private JwtAuthenticationSuccessHandler jwtAuthenticationSuccessHandler; @Override public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication ) throws IOException, ServletException { clearAuthenticationAttributes(request); - User user = (User) authentication.getPrincipal(); - - String jws = tokenHelper.generateToken(user.getUsername()); - - Cookie authCookie = new Cookie( TOKEN_COOKIE, jws ); - authCookie.setHttpOnly(true); - authCookie.setMaxAge(EXPIRES_IN_SEC); - authCookie.setPath( "/quartz-manager" ); - response.addCookie(authCookie); - - // JWT is also in the response - UserTokenState userTokenState = new UserTokenState(jws, EXPIRES_IN_SEC); - String jwtResponse = objectMapper.writeValueAsString( userTokenState ); - response.setContentType("application/json"); - response.getWriter().write( jwtResponse ); - + jwtAuthenticationSuccessHandler.onSuccess(authentication, response); } - // @Override - // public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, - // Authentication authentication ) throws IOException, ServletException { - // // clearAuthenticationAttributes(request); - // response.setContentType("application/json"); - // response.getWriter().write( objectMapper.writeValueAsString("OK")); - // } } diff --git a/quartz-manager-api/src/main/java/it/fabioformosa/quartzmanager/security/auth/JwtAuthenticationFilter.java b/quartz-manager-api/src/main/java/it/fabioformosa/quartzmanager/security/auth/JwtAuthenticationFilter.java index a8ec266..a2bf6b2 100644 --- a/quartz-manager-api/src/main/java/it/fabioformosa/quartzmanager/security/auth/JwtAuthenticationFilter.java +++ b/quartz-manager-api/src/main/java/it/fabioformosa/quartzmanager/security/auth/JwtAuthenticationFilter.java @@ -4,6 +4,7 @@ import javax.servlet.FilterChain; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import lombok.SneakyThrows; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.core.Authentication; import org.springframework.security.core.userdetails.UserDetails; @@ -11,15 +12,20 @@ import org.springframework.security.web.authentication.UsernamePasswordAuthentic import it.fabioformosa.quartzmanager.security.JwtTokenHelper; +import java.io.IOException; + public class JwtAuthenticationFilter extends UsernamePasswordAuthenticationFilter { private final JwtTokenHelper jwtTokenHelper; + private JwtAuthenticationSuccessHandler jwtAuthenticationSuccessHandler; - public JwtAuthenticationFilter(AuthenticationManager authenticationManager, JwtTokenHelper jwtTokenHelper) { + public JwtAuthenticationFilter(AuthenticationManager authenticationManager, JwtTokenHelper jwtTokenHelper, JwtAuthenticationSuccessHandler jwtAuthenticationSuccessHandler) { this.jwtTokenHelper = jwtTokenHelper; + this.jwtAuthenticationSuccessHandler = jwtAuthenticationSuccessHandler; setAuthenticationManager(authenticationManager); } + @SneakyThrows @Override protected void successfulAuthentication(HttpServletRequest req, HttpServletResponse res, @@ -28,5 +34,7 @@ public class JwtAuthenticationFilter extends UsernamePasswordAuthenticationFilte UserDetails user = (UserDetails) auth.getPrincipal(); String token = jwtTokenHelper.generateToken(user.getUsername()); jwtTokenHelper.setHeader(res, token); + + jwtAuthenticationSuccessHandler.onSuccess(auth, res); } -} \ No newline at end of file +} diff --git a/quartz-manager-api/src/main/java/it/fabioformosa/quartzmanager/security/auth/JwtAuthenticationSuccessHandler.java b/quartz-manager-api/src/main/java/it/fabioformosa/quartzmanager/security/auth/JwtAuthenticationSuccessHandler.java new file mode 100644 index 0000000..372b1be --- /dev/null +++ b/quartz-manager-api/src/main/java/it/fabioformosa/quartzmanager/security/auth/JwtAuthenticationSuccessHandler.java @@ -0,0 +1,10 @@ +package it.fabioformosa.quartzmanager.security.auth; + +import org.springframework.security.core.Authentication; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +public interface JwtAuthenticationSuccessHandler { + void onSuccess(Authentication authentication, HttpServletResponse response) throws IOException; +} diff --git a/quartz-manager-api/src/main/java/it/fabioformosa/quartzmanager/security/auth/JwtAuthenticationSuccessHandlerImpl.java b/quartz-manager-api/src/main/java/it/fabioformosa/quartzmanager/security/auth/JwtAuthenticationSuccessHandlerImpl.java new file mode 100644 index 0000000..79f1afc --- /dev/null +++ b/quartz-manager-api/src/main/java/it/fabioformosa/quartzmanager/security/auth/JwtAuthenticationSuccessHandlerImpl.java @@ -0,0 +1,54 @@ +package it.fabioformosa.quartzmanager.security.auth; + +import com.fasterxml.jackson.databind.ObjectMapper; +import it.fabioformosa.quartzmanager.security.JwtTokenHelper; +import it.fabioformosa.quartzmanager.security.model.UserTokenState; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.userdetails.User; +import org.springframework.stereotype.Component; + +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +@Component +public class JwtAuthenticationSuccessHandlerImpl implements JwtAuthenticationSuccessHandler { + + @Value("${quartz-manager.security.jwt.expiration-in-sec}") + private int EXPIRES_IN_SEC; + + @Value("${quartz-manager.security.jwt.cookie}") + private String TOKEN_COOKIE; + + private final JwtTokenHelper jwtTokenHelper; + + private final ObjectMapper objectMapper; + + @Autowired + public JwtAuthenticationSuccessHandlerImpl(JwtTokenHelper tokenHelper, ObjectMapper objectMapper) { + this.jwtTokenHelper = tokenHelper; + this.objectMapper = objectMapper; + } + + @Override + public void onSuccess(Authentication authentication, HttpServletResponse response) throws IOException { + User user = (User) authentication.getPrincipal(); + + String jws = jwtTokenHelper.generateToken(user.getUsername()); + + //set cookie or set header? + Cookie authCookie = new Cookie(TOKEN_COOKIE, jws); + authCookie.setHttpOnly(true); + authCookie.setMaxAge(EXPIRES_IN_SEC); + authCookie.setPath("/quartz-manager"); + response.addCookie(authCookie); + + // JWT is also in the response + UserTokenState userTokenState = new UserTokenState(jws, EXPIRES_IN_SEC); + String jwtResponse = objectMapper.writeValueAsString(userTokenState); + response.setContentType("application/json"); + response.getWriter().write(jwtResponse); + } +} diff --git a/quartz-manager-api/src/main/resources/application.yml b/quartz-manager-api/src/main/resources/application.yml index bfa8435..125dcbc 100644 --- a/quartz-manager-api/src/main/resources/application.yml +++ b/quartz-manager-api/src/main/resources/application.yml @@ -36,7 +36,13 @@ quartz-manager: secret: "bibidibobidiboo" expiration-in-sec: 28800 # 8 hours header: "Authorization" - cookie: AUTH-TOKEN + cookie: AUTH-TOKEN + header-strategy: + enabled: false + header: "Authorization" + cookie-strategy: + enabled: true + cookie: AUTH-TOKEN jobClass: it.fabioformosa.quartzmanager.jobs.myjobs.SampleJob accounts: in-memory: @@ -45,4 +51,4 @@ quartz-manager: - name: admin password: admin roles: - - ADMIN \ No newline at end of file + - ADMIN