#6 step into security refactoring

This commit is contained in:
fabio.formosa
2020-04-22 00:03:31 +02:00
parent 4b7de03050
commit 3b51cd5504
14 changed files with 342 additions and 153 deletions

View File

@@ -164,7 +164,12 @@
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
</dependencies>

View File

@@ -4,7 +4,10 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.authentication.configurers.provisioning.InMemoryUserDetailsManagerConfigurer;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
@@ -14,16 +17,17 @@ import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.authentication.HttpStatusEntryPoint;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import it.fabioformosa.quartzmanager.security.auth.AuthenticationFailureHandler;
import it.fabioformosa.quartzmanager.security.auth.AuthenticationSuccessHandler;
import it.fabioformosa.quartzmanager.configuration.helpers.LoginConfig;
import it.fabioformosa.quartzmanager.configuration.properties.InMemoryAccountProperties;
import it.fabioformosa.quartzmanager.security.auth.LogoutSuccess;
import it.fabioformosa.quartzmanager.security.auth.RestAuthenticationEntryPoint;
import it.fabioformosa.quartzmanager.security.auth.TokenAuthenticationFilter;
/**
@@ -37,91 +41,96 @@ import it.fabioformosa.quartzmanager.security.auth.TokenAuthenticationFilter;
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfigJWT extends WebSecurityConfigurerAdapter {
@Value("${jwt.cookie}")
private String TOKEN_COOKIE;
private static final String[] PATTERNS_SWAGGER_UI = {"/swagger-ui.html", "/v2/api-docs", "/swagger-resources/**", "/webjars/**"};
// @Autowired
// private CustomUserDetailsService jwtUserDetailsService;
@Value("${quartz-manager.security.jwt.cookie}")
private String TOKEN_COOKIE;
@Autowired
private RestAuthenticationEntryPoint restAuthenticationEntryPoint;
// @Autowired
// private CustomUserDetailsService jwtUserDetailsService;
@Autowired
private LogoutSuccess logoutSuccess;
@Autowired
private LogoutSuccess logoutSuccess;
@Autowired
private AuthenticationSuccessHandler authenticationSuccessHandler;
@Autowired
private LoginConfig loginConfigurer;
@Autowired
private AuthenticationFailureHandler authenticationFailureHandler;
@Autowired
private InMemoryAccountProperties inMemoryAccountProps;
@Value("${quartz-manager.account.user}")
private String adminUser;
// @Bean
// @Override
// public AuthenticationManager authenticationManagerBean() throws Exception {
// return super.authenticationManagerBean();
// }
@Value("${quartz-manager.account.pwd}")
private String adminPwd;
@Override
public void configure(AuthenticationManagerBuilder authenticationManagerBuilder)throws Exception {
configureInMemoryAuthentication(authenticationManagerBuilder);
// authenticationManagerBuilder.userDetailsService(jwtUserDetailsService)
// .passwordEncoder(passwordEncoder());
}
// @Bean
// @Override
// public AuthenticationManager authenticationManagerBean() throws Exception {
// return super.authenticationManagerBean();
// }
@Override
protected void configure(HttpSecurity http) throws Exception {
// http.csrf().ignoringAntMatchers("/api/login", "/api/signup") //
// .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()) //
http.csrf().disable() //
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and() //
.exceptionHandling().authenticationEntryPoint(restAuthEntryPoint()).and()
.addFilterBefore(jwtAuthenticationTokenFilter(), BasicAuthenticationFilter.class)
.authorizeRequests().anyRequest().authenticated();
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/css/**", //
"/js/**", //
"/img/**", //
"/lib/**", //
"/swagger-resources/**", "/swagger-ui.html","/v2/api-docs", //
"/webjars/**");
}
loginConfigurer.configureLoginHandler(http, authenticationManager()).logout().logoutRequestMatcher(new AntPathRequestMatcher("/api/logout"))
.logoutSuccessHandler(logoutSuccess).deleteCookies(TOKEN_COOKIE);
@Autowired
public void configureGlobal(AuthenticationManagerBuilder authenticationManagerBuilder)
throws Exception {
// authenticationManagerBuilder.userDetailsService(jwtUserDetailsService)
// .passwordEncoder(passwordEncoder());
PasswordEncoder encoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
authenticationManagerBuilder.inMemoryAuthentication().withUser(adminUser).password(encoder.encode(adminPwd)).roles("ADMIN");
}
}
@Bean
public TokenAuthenticationFilter jwtAuthenticationTokenFilter() throws Exception {
return new TokenAuthenticationFilter();
}
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring()//
.antMatchers(HttpMethod.GET, PATTERNS_SWAGGER_UI) //
.antMatchers(HttpMethod.GET,"/css/**", "/js/**", "/img/**", "/lib/**");
}
@Bean
@Override
public UserDetailsService userDetailsServiceBean() throws Exception {
return super.userDetailsServiceBean();
}
private void configureInMemoryAuthentication(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
PasswordEncoder encoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
if(inMemoryAccountProps.isEnabled() && inMemoryAccountProps.getUsers() != null && !inMemoryAccountProps.getUsers().isEmpty()) {
InMemoryUserDetailsManagerConfigurer<AuthenticationManagerBuilder> inMemoryAuth = authenticationManagerBuilder.inMemoryAuthentication();
inMemoryAccountProps.getUsers()
.forEach(u -> inMemoryAuth
.withUser(u.getName())
.password(encoder.encode(u.getPassword()))
.roles(u.getRoles().toArray(new String[0])));
}
}
// @Bean
// public PasswordEncoder passwordEncoder() {
// return new BCryptPasswordEncoder();
// }
@Bean
CorsConfigurationSource corsConfigurationSource() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", new CorsConfiguration().applyPermitDefaultValues());
return source;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
// http.csrf().ignoringAntMatchers("/api/login", "/api/signup") //
// .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()) //
http.csrf().disable() //
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and() //
.exceptionHandling().authenticationEntryPoint(restAuthenticationEntryPoint).and()
.addFilterBefore(jwtAuthenticationTokenFilter(), BasicAuthenticationFilter.class)
.authorizeRequests().anyRequest().authenticated().and().formLogin().loginPage("/api/login")
.successHandler(authenticationSuccessHandler).failureHandler(authenticationFailureHandler)
.and().logout().logoutRequestMatcher(new AntPathRequestMatcher("/api/logout"))
.logoutSuccessHandler(logoutSuccess).deleteCookies(TOKEN_COOKIE);
@Bean
public TokenAuthenticationFilter jwtAuthenticationTokenFilter() throws Exception {
return new TokenAuthenticationFilter();
}
}
// @Bean
// public PasswordEncoder passwordEncoder() {
// return new BCryptPasswordEncoder();
// }
@Bean
CorsConfigurationSource corsConfigurationSource() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", new CorsConfiguration().applyPermitDefaultValues());
return source;
}
@Bean
public AuthenticationEntryPoint restAuthEntryPoint() {
return new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED);
}
@Bean
@Override
public UserDetailsService userDetailsServiceBean() throws Exception {
return super.userDetailsServiceBean();
}
}

View File

@@ -0,0 +1,10 @@
package it.fabioformosa.quartzmanager.configuration.helpers;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
public interface LoginConfig {
HttpSecurity configureLoginHandler(HttpSecurity http, AuthenticationManager authenticationManager) throws Exception;
}

View File

@@ -0,0 +1,31 @@
package it.fabioformosa.quartzmanager.configuration.helpers.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.stereotype.Component;
import it.fabioformosa.quartzmanager.configuration.helpers.LoginConfig;
import it.fabioformosa.quartzmanager.security.auth.AuthenticationFailureHandler;
import it.fabioformosa.quartzmanager.security.auth.AuthenticationSuccessHandler;
@Component
@ConditionalOnProperty(prefix = "quartz-manager.security.login-model", name = "form-login-enabled", havingValue = "true", matchIfMissing = true)
public class FormLoginConfig implements LoginConfig {
private static final String API_LOGIN = "/api/login";
@Autowired
private AuthenticationSuccessHandler authenticationSuccessHandler;
@Autowired
private AuthenticationFailureHandler authenticationFailureHandler;
@Override
public HttpSecurity configureLoginHandler(
HttpSecurity http, AuthenticationManager authenticationManager) throws Exception {
return http.formLogin().loginPage(API_LOGIN).successHandler(authenticationSuccessHandler).failureHandler(authenticationFailureHandler).and();
}
}

View File

@@ -0,0 +1,37 @@
package it.fabioformosa.quartzmanager.configuration.helpers.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.authentication.preauth.AbstractPreAuthenticatedProcessingFilter;
import org.springframework.security.web.util.matcher.RegexRequestMatcher;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.GenericFilterBean;
import it.fabioformosa.quartzmanager.configuration.helpers.LoginConfig;
import it.fabioformosa.quartzmanager.security.JwtTokenHelper;
import it.fabioformosa.quartzmanager.security.auth.JwtAuthenticationFilter;
@Component
@ConditionalOnProperty(prefix = "quartz-manager.security.login-model", name = "userpwd-filter-enabled", havingValue = "true", matchIfMissing = false)
public class UsernamePasswordFiterLoginConfig implements LoginConfig {
private static final String API_LOGIN = "/api/login";
@Autowired
private JwtTokenHelper jwtTokenHelper;
public GenericFilterBean authenticationProcessingFilter(AuthenticationManager authenticationManager) throws Exception {
JwtAuthenticationFilter authenticationProcessingFilter = new JwtAuthenticationFilter(authenticationManager, jwtTokenHelper);
authenticationProcessingFilter.setRequiresAuthenticationRequestMatcher(new RegexRequestMatcher(API_LOGIN, HttpMethod.POST.name(), false));
return authenticationProcessingFilter;
}
@Override
public HttpSecurity configureLoginHandler(HttpSecurity http, AuthenticationManager authenticationManager) throws Exception {
return http.addFilterAfter(authenticationProcessingFilter(authenticationManager), AbstractPreAuthenticatedProcessingFilter.class);
}
}

View File

@@ -0,0 +1,24 @@
package it.fabioformosa.quartzmanager.configuration.properties;
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import java.util.ArrayList;
import java.util.List;
@Configuration
@ConfigurationProperties(prefix = "quartz-manager.accounts.in-memory")
@Getter @Setter
public class InMemoryAccountProperties {
private boolean enabled;
private List<User> users;
@Getter @Setter
public static class User {
private String name;
private String password;
private List<String> roles = new ArrayList<>();
}
}

View File

@@ -0,0 +1,17 @@
package it.fabioformosa.quartzmanager.configuration.properties;
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
@Configuration
@ConfigurationProperties(prefix = "quartz-manager.security.jwt")
@Getter @Setter
public class JwtSecurityProperties {
private boolean enabled;
private String secret;
private long expirationInSec;
private String header;
private String cookie;
}

View File

@@ -15,7 +15,7 @@ import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import it.fabioformosa.quartzmanager.security.TokenHelper;
import it.fabioformosa.quartzmanager.security.JwtTokenHelper;
import it.fabioformosa.quartzmanager.security.model.UserTokenState;
import it.fabioformosa.quartzmanager.security.service.impl.CustomUserDetailsService;
@@ -39,12 +39,12 @@ public class AuthenticationController {
private CustomUserDetailsService userDetailsService;
@Autowired
TokenHelper tokenHelper;
JwtTokenHelper tokenHelper;
@Value("${jwt.expires_in_sec}")
@Value("${quartz-manager.security.jwt.expiration-in-sec}")
private int EXPIRES_IN_SEC;
@Value("${jwt.cookie}")
@Value("${quartz-manager.security.jwt.cookie}")
private String TOKEN_COOKIE;
@RequestMapping(value = "/changePassword", method = RequestMethod.POST)

View File

@@ -1,22 +1,26 @@
package it.fabioformosa.quartzmanager.security;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.Date;
import java.util.Map;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import it.fabioformosa.quartzmanager.configuration.properties.JwtSecurityProperties;
import lombok.extern.slf4j.Slf4j;
/**
* JWT Temporary disabled
*
* @author Fabio.Formosa
*
@@ -24,25 +28,32 @@ import lombok.extern.slf4j.Slf4j;
@Slf4j
@Component
public class TokenHelper {
public class JwtTokenHelper {
private static String base64EncodeSecretKey(String secretKey) {
return Base64.getEncoder().encodeToString(secretKey.getBytes(StandardCharsets.UTF_8));
}
@Value("${app.name}")
private String APP_NAME;
@Value("${jwt.secret}")
private String SECRET;
@Value("${jwt.expires_in_sec}")
private int EXPIRES_IN_SEC;
@Value("${jwt.header}")
private String AUTH_HEADER;
@Value("${jwt.cookie}")
private String AUTH_COOKIE;
// @Value("${jwt.secret}")
// private String SECRET;
//
// @Value("${jwt.expires_in_sec}")
// private int EXPIRES_IN_SEC;
//
// @Value("${jwt.header}")
// private String AUTH_HEADER;
// @Autowired
// UserDetailsService userDetailsService;
//
// @Value("${jwt.cookie}")
// private String AUTH_COOKIE;
@Autowired
private JwtSecurityProperties jwtSecurityProps;
private SignatureAlgorithm SIGNATURE_ALGORITHM = SignatureAlgorithm.HS512;
@@ -62,14 +73,14 @@ public class TokenHelper {
}
private Date generateExpirationDate() {
return new Date(getCurrentTimeMillis() + EXPIRES_IN_SEC * 1000);
return new Date(getCurrentTimeMillis() + jwtSecurityProps.getExpirationInSec() * 1000);
}
String generateToken(Map<String, Object> claims) {
private String generateToken(Map<String, Object> claims) {
return Jwts.builder()
.setClaims(claims)
.setExpiration(generateExpirationDate())
.signWith( SIGNATURE_ALGORITHM, SECRET )
.signWith( SIGNATURE_ALGORITHM, base64EncodeSecretKey(jwtSecurityProps.getSecret()))
.compact();
}
@@ -79,7 +90,7 @@ public class TokenHelper {
.setSubject(username)
.setIssuedAt(generateCurrentDate())
.setExpiration(generateExpirationDate())
.signWith(SIGNATURE_ALGORITHM, SECRET)
.signWith(SIGNATURE_ALGORITHM, base64EncodeSecretKey(jwtSecurityProps.getSecret()))
.compact();
}
@@ -87,7 +98,7 @@ public class TokenHelper {
Claims claims;
try {
claims = Jwts.parser()
.setSigningKey(SECRET)
.setSigningKey(base64EncodeSecretKey(jwtSecurityProps.getSecret()))
.parseClaimsJws(token)
.getBody();
} catch (Exception e) {
@@ -119,12 +130,12 @@ public class TokenHelper {
return DateTime.now().getMillis();
}
public String getToken( HttpServletRequest request ) {
Cookie authCookie = getCookieValueByName( request, AUTH_COOKIE );
public String getToken(HttpServletRequest request) {
Cookie authCookie = getCookieValueByName(request, jwtSecurityProps.getCookie());
if ( authCookie != null )
return authCookie.getValue();
String authHeader = request.getHeader(AUTH_HEADER);
String authHeader = request.getHeader(jwtSecurityProps.getHeader());
if ( authHeader != null && authHeader.startsWith("Bearer "))
return authHeader.substring(7);
@@ -155,4 +166,8 @@ public class TokenHelper {
}
return refreshedToken;
}
public void setHeader(HttpServletResponse response, String token) {
response.addHeader(jwtSecurityProps.getHeader(), "Bearer " + token);
}
}

View File

@@ -6,17 +6,19 @@ import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
import org.springframework.stereotype.Component;
@Component
@ConditionalOnProperty(prefix = "quartz-manager.security.login-model", name = "form-login-enabled", havingValue = "true", matchIfMissing = true)
public class AuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler {
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
AuthenticationException exception) throws IOException, ServletException {
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
AuthenticationException exception) throws IOException, ServletException {
super.onAuthenticationFailure(request, response, exception);
}
super.onAuthenticationFailure(request, response, exception);
}
}

View File

@@ -9,6 +9,7 @@ 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;
@@ -16,54 +17,52 @@ import org.springframework.stereotype.Component;
import com.fasterxml.jackson.databind.ObjectMapper;
import it.fabioformosa.quartzmanager.security.TokenHelper;
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("${jwt.expires_in_sec}")
private int EXPIRES_IN_SEC;
@Value("${quartz-manager.security.jwt.expiration-in-sec}")
private int EXPIRES_IN_SEC;
@Value("${jwt.cookie}")
private String TOKEN_COOKIE;
@Value("${quartz-manager.security.jwt.cookie}")
private String TOKEN_COOKIE;
@Autowired
TokenHelper tokenHelper;
//
@Autowired
ObjectMapper objectMapper;
@Autowired
JwtTokenHelper tokenHelper;
//
@Autowired
ObjectMapper objectMapper;
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication ) throws IOException, ServletException {
clearAuthenticationAttributes(request);
User user = (User)authentication.getPrincipal();
@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() );
String jws = tokenHelper.generateToken(user.getUsername());
Cookie authCookie = new Cookie( TOKEN_COOKIE, jws );
Cookie authCookie = new Cookie( TOKEN_COOKIE, jws );
authCookie.setHttpOnly(true);
authCookie.setMaxAge(EXPIRES_IN_SEC);
authCookie.setPath( "/quartz-manager" );
response.addCookie(authCookie);
authCookie.setHttpOnly( true );
// 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 );
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 );
}
// @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"));
// }
// @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"));
// }
}

View File

@@ -0,0 +1,32 @@
package it.fabioformosa.quartzmanager.security.auth;
import javax.servlet.FilterChain;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import it.fabioformosa.quartzmanager.security.JwtTokenHelper;
public class JwtAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
private final JwtTokenHelper jwtTokenHelper;
public JwtAuthenticationFilter(AuthenticationManager authenticationManager, JwtTokenHelper jwtTokenHelper) {
this.jwtTokenHelper = jwtTokenHelper;
setAuthenticationManager(authenticationManager);
}
@Override
protected void successfulAuthentication(HttpServletRequest req,
HttpServletResponse res,
FilterChain chain,
Authentication auth) {
UserDetails user = (UserDetails) auth.getPrincipal();
String token = jwtTokenHelper.generateToken(user.getUsername());
jwtTokenHelper.setHeader(res, token);
}
}

View File

@@ -20,7 +20,7 @@ import org.springframework.security.web.util.matcher.RequestMatcher;
import org.springframework.util.Assert;
import org.springframework.web.filter.OncePerRequestFilter;
import it.fabioformosa.quartzmanager.security.TokenHelper;
import it.fabioformosa.quartzmanager.security.JwtTokenHelper;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@@ -38,7 +38,7 @@ public class TokenAuthenticationFilter extends OncePerRequestFilter {
// private final Log logger = LogFactory.getLog(this.getClass());
@Autowired
private TokenHelper tokenHelper;
private JwtTokenHelper tokenHelper;
@Autowired
private UserDetailsService userDetailsService;

View File

@@ -19,12 +19,6 @@ job:
frequency: 4000
repeatCount: 19
jwt:
header: Authorization
expires_in_sec: 600 # 10 minutes
secret: queenvictoria
cookie: AUTH-TOKEN
logging:
level:
org.springframework.web: WARN
@@ -33,8 +27,22 @@ logging:
it.fabioformosa: DEBUG
quartz-manager:
security:
login-model:
form-login-enabled: true
userpwd-filter-enabled : false
jwt:
enabled: true
secret: "bibidibobidiboo"
expiration-in-sec: 28800 # 8 hours
header: "Authorization"
cookie: AUTH-TOKEN
jobClass: it.fabioformosa.quartzmanager.jobs.myjobs.SampleJob
account:
user: admin
pwd: admin
accounts:
in-memory:
enabled: true
users:
- name: admin
password: admin
roles:
- ADMIN