mirror of
https://github.com/fabioformosa/quartz-manager.git
synced 2026-05-14 22:00:30 +09:00
#6 refactoring completed
This commit is contained in:
@@ -26,6 +26,7 @@
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<!-- SPRING -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
@@ -58,6 +59,11 @@
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-tx</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-tomcat</artifactId>
|
||||
@@ -69,6 +75,7 @@
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- MISC -->
|
||||
<dependency>
|
||||
<groupId>io.jsonwebtoken</groupId>
|
||||
<artifactId>jjwt</artifactId>
|
||||
@@ -91,23 +98,31 @@
|
||||
<artifactId>h2</artifactId>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.codehaus.groovy</groupId>
|
||||
<artifactId>groovy</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>net.sourceforge.nekohtml</groupId>
|
||||
<artifactId>nekohtml</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.rest-assured</groupId>
|
||||
<artifactId>spring-mock-mvc</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>3.10</version>
|
||||
</dependency>
|
||||
|
||||
<!-- QUARTZ -->
|
||||
<dependency>
|
||||
<groupId>org.quartz-scheduler</groupId>
|
||||
<artifactId>quartz</artifactId>
|
||||
@@ -158,18 +173,6 @@
|
||||
<version>${springfox.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package it.fabioformosa.quartzmanager.configuration;
|
||||
|
||||
import it.fabioformosa.quartzmanager.configuration.helpers.impl.QuartzManagerHttpSecurity;
|
||||
import org.apache.commons.lang3.BooleanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
@@ -21,15 +21,25 @@ 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.configuration.helpers.LoginConfig;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
import it.fabioformosa.quartzmanager.configuration.helpers.LoginConfigurer;
|
||||
import it.fabioformosa.quartzmanager.configuration.helpers.impl.FormLoginConfig;
|
||||
import it.fabioformosa.quartzmanager.configuration.helpers.impl.QuartzManagerHttpSecurity;
|
||||
import it.fabioformosa.quartzmanager.configuration.helpers.impl.UsernamePasswordFiterLoginConfig;
|
||||
import it.fabioformosa.quartzmanager.configuration.properties.InMemoryAccountProperties;
|
||||
import it.fabioformosa.quartzmanager.configuration.properties.JwtSecurityProperties;
|
||||
import it.fabioformosa.quartzmanager.security.JwtTokenHelper;
|
||||
import it.fabioformosa.quartzmanager.security.auth.AuthenticationFailureHandler;
|
||||
import it.fabioformosa.quartzmanager.security.auth.AuthenticationSuccessHandler;
|
||||
import it.fabioformosa.quartzmanager.security.auth.JwtAuthenticationSuccessHandler;
|
||||
import it.fabioformosa.quartzmanager.security.auth.JwtAuthenticationSuccessHandlerImpl;
|
||||
import it.fabioformosa.quartzmanager.security.auth.JwtTokenAuthenticationFilter;
|
||||
import it.fabioformosa.quartzmanager.security.auth.LogoutSuccess;
|
||||
import it.fabioformosa.quartzmanager.security.auth.TokenAuthenticationFilter;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -43,18 +53,32 @@ public class WebSecurityConfigJWT extends WebSecurityConfigurerAdapter {
|
||||
|
||||
private static final String[] PATTERNS_SWAGGER_UI = {"/swagger-ui.html", "/v2/api-docs", "/swagger-resources/**", "/webjars/**"};
|
||||
|
||||
@Value("${quartz-manager.security.jwt.cookie-strategy.cookie}")
|
||||
private String TOKEN_COOKIE;
|
||||
private static final String LOGIN_PATH = "/api/login";
|
||||
private static final String LOGOUT_PATH = "/api/logout";
|
||||
|
||||
@Value("${server.servlet.context-path}")
|
||||
private String contextPath;
|
||||
|
||||
@Value("${app.name}")
|
||||
private String APP_NAME;
|
||||
|
||||
@Value("${quartz-manager.security.login-model.form-login-enabled}")
|
||||
private Boolean formLoginEnabled;
|
||||
@Value("${quartz-manager.security.login-model.userpwd-filter-enabled}")
|
||||
private Boolean userpwdFilterEnabled;
|
||||
|
||||
@Autowired
|
||||
private JwtSecurityProperties jwtSecurityProps;
|
||||
|
||||
@Autowired
|
||||
private ObjectMapper objectMapper;
|
||||
|
||||
@Autowired
|
||||
private UserDetailsService userDetailsService;
|
||||
|
||||
// @Autowired
|
||||
// private CustomUserDetailsService jwtUserDetailsService;
|
||||
|
||||
@Autowired
|
||||
private LogoutSuccess logoutSuccess;
|
||||
|
||||
@Autowired
|
||||
private LoginConfig loginConfig;
|
||||
|
||||
@Autowired
|
||||
private InMemoryAccountProperties inMemoryAccountProps;
|
||||
|
||||
@@ -82,8 +106,7 @@ public class WebSecurityConfigJWT extends WebSecurityConfigurerAdapter {
|
||||
.addFilterBefore(jwtAuthenticationTokenFilter(), BasicAuthenticationFilter.class) //
|
||||
.authorizeRequests().anyRequest().authenticated();
|
||||
|
||||
QuartzManagerHttpSecurity.from(http).login(authenticationManager()).logout().logoutRequestMatcher(new AntPathRequestMatcher("/api/logout"))
|
||||
.logoutSuccessHandler(logoutSuccess).deleteCookies(TOKEN_COOKIE);
|
||||
QuartzManagerHttpSecurity.from(http).loginConfig(loginConfigurer(), logoutConfigurer()).login(LOGIN_PATH, authenticationManager()).logout(LOGOUT_PATH);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -113,8 +136,49 @@ public class WebSecurityConfigJWT extends WebSecurityConfigurerAdapter {
|
||||
}
|
||||
|
||||
@Bean
|
||||
public TokenAuthenticationFilter jwtAuthenticationTokenFilter() throws Exception {
|
||||
return new TokenAuthenticationFilter();
|
||||
public LoginConfigurer formLoginConfigurer() {
|
||||
JwtAuthenticationSuccessHandler jwtAuthenticationSuccessHandler = jwtAuthenticationSuccessHandler();
|
||||
AuthenticationSuccessHandler authenticationSuccessHandler = new AuthenticationSuccessHandler(jwtAuthenticationSuccessHandler);
|
||||
AuthenticationFailureHandler authenticationFailureHandler = new AuthenticationFailureHandler();
|
||||
LoginConfigurer loginConfigurer = new FormLoginConfig(authenticationSuccessHandler, authenticationFailureHandler);
|
||||
return loginConfigurer;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public JwtAuthenticationSuccessHandler jwtAuthenticationSuccessHandler() {
|
||||
JwtTokenHelper jwtTokenHelper = jwtTokenHelper();
|
||||
JwtAuthenticationSuccessHandler jwtAuthenticationSuccessHandler = new JwtAuthenticationSuccessHandlerImpl(contextPath, jwtSecurityProps, jwtTokenHelper, objectMapper);
|
||||
return jwtAuthenticationSuccessHandler;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public JwtTokenAuthenticationFilter jwtAuthenticationTokenFilter() throws Exception {
|
||||
return new JwtTokenAuthenticationFilter(jwtTokenHelper(), userDetailsService);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public JwtTokenHelper jwtTokenHelper() {
|
||||
JwtTokenHelper jwtTokenHelper = new JwtTokenHelper(APP_NAME, jwtSecurityProps);
|
||||
return jwtTokenHelper;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public LoginConfigurer loginConfigurer() {
|
||||
if(BooleanUtils.isTrue(userpwdFilterEnabled))
|
||||
return userpwdFilterLoginConfigurer();
|
||||
if(BooleanUtils.isNotFalse(formLoginEnabled))
|
||||
return formLoginConfigurer();
|
||||
throw new RuntimeException("No login configurer enabled!");
|
||||
}
|
||||
|
||||
@Bean
|
||||
public LogoutSuccess logoutConfigurer() {
|
||||
return new LogoutSuccess(objectMapper);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public AuthenticationEntryPoint restAuthEntryPoint() {
|
||||
return new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED);
|
||||
}
|
||||
|
||||
// @Bean
|
||||
@@ -122,15 +186,16 @@ public class WebSecurityConfigJWT extends WebSecurityConfigurerAdapter {
|
||||
// return new BCryptPasswordEncoder();
|
||||
// }
|
||||
|
||||
@Bean
|
||||
public AuthenticationEntryPoint restAuthEntryPoint() {
|
||||
return new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Override
|
||||
public UserDetailsService userDetailsServiceBean() throws Exception {
|
||||
return super.userDetailsServiceBean();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public LoginConfigurer userpwdFilterLoginConfigurer() {
|
||||
LoginConfigurer loginConfigurer = new UsernamePasswordFiterLoginConfig(jwtAuthenticationSuccessHandler());
|
||||
return loginConfigurer;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -3,8 +3,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 {
|
||||
public interface LoginConfigurer {
|
||||
|
||||
HttpSecurity login(HttpSecurity http, AuthenticationManager authenticationManager) throws Exception;
|
||||
String cookieMustBeDeletedAtLogout();
|
||||
|
||||
HttpSecurity login(String loginPath, HttpSecurity http, AuthenticationManager authenticationManager) throws Exception;
|
||||
|
||||
}
|
||||
@@ -1,31 +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.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.configuration.helpers.LoginConfigurer;
|
||||
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 {
|
||||
//@Component
|
||||
//@ConditionalOnProperty(prefix = "quartz-manager.security.login-model", name = "form-login-enabled", havingValue = "true", matchIfMissing = true)
|
||||
public class FormLoginConfig implements LoginConfigurer {
|
||||
|
||||
private static final String API_LOGIN = "/api/login";
|
||||
private final AuthenticationSuccessHandler authenticationSuccessHandler;
|
||||
|
||||
@Autowired
|
||||
private AuthenticationSuccessHandler authenticationSuccessHandler;
|
||||
private final AuthenticationFailureHandler authenticationFailureHandler;
|
||||
|
||||
@Autowired
|
||||
private AuthenticationFailureHandler authenticationFailureHandler;
|
||||
// @Autowired
|
||||
public FormLoginConfig(AuthenticationSuccessHandler authenticationSuccessHandler,
|
||||
AuthenticationFailureHandler authenticationFailureHandler) {
|
||||
super();
|
||||
this.authenticationSuccessHandler = authenticationSuccessHandler;
|
||||
this.authenticationFailureHandler = authenticationFailureHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpSecurity login(
|
||||
public String cookieMustBeDeletedAtLogout() {
|
||||
return authenticationSuccessHandler.cookieMustBeDeletedAtLogout();
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpSecurity login(String loginPath,
|
||||
HttpSecurity http, AuthenticationManager authenticationManager) throws Exception {
|
||||
return http.formLogin().loginPage(API_LOGIN).successHandler(authenticationSuccessHandler).failureHandler(authenticationFailureHandler).and();
|
||||
return http.formLogin().loginPage(loginPath).successHandler(authenticationSuccessHandler).failureHandler(authenticationFailureHandler).and();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,39 +1,54 @@
|
||||
package it.fabioformosa.quartzmanager.configuration.helpers.impl;
|
||||
|
||||
import it.fabioformosa.quartzmanager.configuration.helpers.LoginConfig;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
import org.springframework.security.config.annotation.SecurityConfigurerAdapter;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.configurers.LogoutConfigurer;
|
||||
import org.springframework.security.web.DefaultSecurityFilterChain;
|
||||
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
|
||||
|
||||
import it.fabioformosa.quartzmanager.configuration.helpers.LoginConfigurer;
|
||||
import it.fabioformosa.quartzmanager.security.auth.LogoutSuccess;
|
||||
|
||||
public class QuartzManagerHttpSecurity extends SecurityConfigurerAdapter<DefaultSecurityFilterChain, HttpSecurity> {
|
||||
|
||||
private ApplicationContext applicationContext;
|
||||
private HttpSecurity httpSecurity;
|
||||
|
||||
private final LoginConfig loginConfig;
|
||||
|
||||
public static QuartzManagerHttpSecurity from(HttpSecurity httpSecurity){
|
||||
QuartzManagerHttpSecurity newInstance = new QuartzManagerHttpSecurity(httpSecurity);
|
||||
newInstance.setBuilder(httpSecurity);
|
||||
return newInstance;
|
||||
}
|
||||
|
||||
private HttpSecurity httpSecurity;
|
||||
|
||||
private LoginConfigurer loginConfiger;
|
||||
|
||||
private LogoutSuccess logoutSuccess;
|
||||
|
||||
public QuartzManagerHttpSecurity(HttpSecurity httpSecurity) {
|
||||
this.httpSecurity = httpSecurity;
|
||||
this.applicationContext = httpSecurity.getSharedObject(ApplicationContext.class);
|
||||
this.loginConfig = this.applicationContext.getBean(LoginConfig.class);
|
||||
// applicationContext = httpSecurity.getSharedObject(ApplicationContext.class);
|
||||
// loginConfiger = applicationContext.getBean(LoginConfigurer.class);
|
||||
// logoutSuccess = applicationContext.getBean(LogoutSuccess.class);
|
||||
}
|
||||
|
||||
public QuartzManagerHttpSecurity login(AuthenticationManager authenticationManager) throws Exception {
|
||||
httpSecurity = loginConfig.login(httpSecurity, authenticationManager);
|
||||
public QuartzManagerHttpSecurity login(String loginPath, AuthenticationManager authenticationManager) throws Exception {
|
||||
httpSecurity = loginConfiger.login(loginPath, httpSecurity, authenticationManager);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public LogoutConfigurer<HttpSecurity> logout() throws Exception {
|
||||
return httpSecurity.logout();
|
||||
public QuartzManagerHttpSecurity loginConfig(LoginConfigurer loginConfigurer, LogoutSuccess logoutSuccess) {
|
||||
loginConfiger = loginConfigurer;
|
||||
this.logoutSuccess = logoutSuccess;
|
||||
return this;
|
||||
}
|
||||
|
||||
public LogoutConfigurer<HttpSecurity> logout(String logoutPath) throws Exception {
|
||||
LogoutConfigurer<HttpSecurity> logoutConfigurer = httpSecurity.logout().logoutRequestMatcher(new AntPathRequestMatcher(logoutPath))
|
||||
.logoutSuccessHandler(logoutSuccess);
|
||||
String cookie = loginConfiger.cookieMustBeDeletedAtLogout();
|
||||
if(cookie != null)
|
||||
logoutConfigurer.deleteCookies(cookie);
|
||||
return logoutConfigurer;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,37 +1,42 @@
|
||||
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.configuration.helpers.LoginConfigurer;
|
||||
import it.fabioformosa.quartzmanager.security.auth.JwtAuthenticationFilter;
|
||||
import it.fabioformosa.quartzmanager.security.auth.JwtAuthenticationSuccessHandler;
|
||||
|
||||
@Component
|
||||
@ConditionalOnProperty(prefix = "quartz-manager.security.login-model", name = "userpwd-filter-enabled", havingValue = "true", matchIfMissing = false)
|
||||
public class UsernamePasswordFiterLoginConfig implements LoginConfig {
|
||||
//@Component
|
||||
//@ConditionalOnProperty(prefix = "quartz-manager.security.login-model", name = "userpwd-filter-enabled", havingValue = "true", matchIfMissing = false)
|
||||
public class UsernamePasswordFiterLoginConfig implements LoginConfigurer {
|
||||
|
||||
private static final String API_LOGIN = "/api/login";
|
||||
// @Autowired
|
||||
private final JwtAuthenticationSuccessHandler jwtAuthenticationSuccessHandler;
|
||||
|
||||
@Autowired
|
||||
private JwtAuthenticationSuccessHandler jwtAuthenticationSuccessHandler;
|
||||
public UsernamePasswordFiterLoginConfig(JwtAuthenticationSuccessHandler jwtAuthenticationSuccessHandler) {
|
||||
super();
|
||||
this.jwtAuthenticationSuccessHandler = jwtAuthenticationSuccessHandler;
|
||||
}
|
||||
|
||||
public GenericFilterBean authenticationProcessingFilter(AuthenticationManager authenticationManager) throws Exception {
|
||||
public GenericFilterBean authenticationProcessingFilter(String loginPath, AuthenticationManager authenticationManager) throws Exception {
|
||||
JwtAuthenticationFilter authenticationProcessingFilter = new JwtAuthenticationFilter(authenticationManager, jwtAuthenticationSuccessHandler);
|
||||
authenticationProcessingFilter.setRequiresAuthenticationRequestMatcher(new RegexRequestMatcher(API_LOGIN, HttpMethod.POST.name(), false));
|
||||
authenticationProcessingFilter.setRequiresAuthenticationRequestMatcher(new RegexRequestMatcher(loginPath, HttpMethod.POST.name(), false));
|
||||
return authenticationProcessingFilter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpSecurity login(HttpSecurity http, AuthenticationManager authenticationManager) throws Exception {
|
||||
return http.addFilterAfter(authenticationProcessingFilter(authenticationManager), AbstractPreAuthenticatedProcessingFilter.class);
|
||||
public String cookieMustBeDeletedAtLogout() {
|
||||
return jwtAuthenticationSuccessHandler.cookieMustBeDeletedAtLogout();
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpSecurity login(String loginPath, HttpSecurity http, AuthenticationManager authenticationManager) throws Exception {
|
||||
return http.addFilterAfter(authenticationProcessingFilter(loginPath, authenticationManager), AbstractPreAuthenticatedProcessingFilter.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ public class AuthenticationController {
|
||||
@RequestMapping(value = "/refresh", method = RequestMethod.GET)
|
||||
public ResponseEntity<?> refreshAuthenticationToken(HttpServletRequest request, HttpServletResponse response) {
|
||||
|
||||
String authToken = tokenHelper.getToken( request );
|
||||
String authToken = tokenHelper.retrieveToken( request );
|
||||
if (authToken != null && tokenHelper.canTokenBeRefreshed(authToken)) {
|
||||
// TODO check user password last update
|
||||
String refreshedToken = tokenHelper.refreshToken(authToken);
|
||||
|
||||
@@ -10,9 +10,6 @@ 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;
|
||||
@@ -27,22 +24,27 @@ import lombok.extern.slf4j.Slf4j;
|
||||
*/
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
//@Component
|
||||
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;
|
||||
|
||||
|
||||
@Autowired
|
||||
private JwtSecurityProperties jwtSecurityProps;
|
||||
// @Value("${app.name}")
|
||||
private final String appName;
|
||||
// @Autowired
|
||||
private final JwtSecurityProperties jwtSecurityProps;
|
||||
|
||||
private SignatureAlgorithm SIGNATURE_ALGORITHM = SignatureAlgorithm.HS512;
|
||||
|
||||
// @Autowired
|
||||
public JwtTokenHelper(String appName, JwtSecurityProperties jwtSecurityProps) {
|
||||
super();
|
||||
this.appName = appName;
|
||||
this.jwtSecurityProps = jwtSecurityProps;
|
||||
}
|
||||
|
||||
public Boolean canTokenBeRefreshed(String token) {
|
||||
try {
|
||||
final Date expirationDate = getClaimsFromToken(token).getExpiration();
|
||||
@@ -63,30 +65,21 @@ public class JwtTokenHelper {
|
||||
}
|
||||
|
||||
private String generateToken(Map<String, Object> claims) {
|
||||
return Jwts.builder()
|
||||
.setClaims(claims)
|
||||
.setExpiration(generateExpirationDate())
|
||||
.signWith( SIGNATURE_ALGORITHM, base64EncodeSecretKey(jwtSecurityProps.getSecret()))
|
||||
.compact();
|
||||
return Jwts.builder().setClaims(claims).setExpiration(generateExpirationDate())
|
||||
.signWith(SIGNATURE_ALGORITHM, base64EncodeSecretKey(jwtSecurityProps.getSecret())).compact();
|
||||
}
|
||||
|
||||
public String generateToken(String username) {
|
||||
return Jwts.builder()
|
||||
.setIssuer(APP_NAME)
|
||||
.setSubject(username)
|
||||
.setIssuedAt(generateCurrentDate())
|
||||
return Jwts.builder().setIssuer(appName).setSubject(username).setIssuedAt(generateCurrentDate())
|
||||
.setExpiration(generateExpirationDate())
|
||||
.signWith(SIGNATURE_ALGORITHM, base64EncodeSecretKey(jwtSecurityProps.getSecret()))
|
||||
.compact();
|
||||
.signWith(SIGNATURE_ALGORITHM, base64EncodeSecretKey(jwtSecurityProps.getSecret())).compact();
|
||||
}
|
||||
|
||||
private Claims getClaimsFromToken(String token) {
|
||||
Claims claims;
|
||||
try {
|
||||
claims = Jwts.parser()
|
||||
.setSigningKey(base64EncodeSecretKey(jwtSecurityProps.getSecret()))
|
||||
.parseClaimsJws(token)
|
||||
.getBody();
|
||||
claims = Jwts.parser().setSigningKey(base64EncodeSecretKey(jwtSecurityProps.getSecret()))
|
||||
.parseClaimsJws(token).getBody();
|
||||
} catch (Exception e) {
|
||||
claims = null;
|
||||
log.error("Error getting claims from jwt token due to " + e.getMessage(), e);
|
||||
@@ -98,9 +91,9 @@ public class JwtTokenHelper {
|
||||
* Find a specific HTTP cookie in a request.
|
||||
*
|
||||
* @param request
|
||||
* The HTTP request object.
|
||||
* The HTTP request object.
|
||||
* @param name
|
||||
* The cookie name to look for.
|
||||
* The cookie name to look for.
|
||||
* @return The cookie, or <code>null</code> if not found.
|
||||
*/
|
||||
public Cookie getCookieValueByName(HttpServletRequest request, String name) {
|
||||
@@ -116,18 +109,6 @@ public class JwtTokenHelper {
|
||||
return DateTime.now().getMillis();
|
||||
}
|
||||
|
||||
public String getToken(HttpServletRequest request) {
|
||||
Cookie authCookie = getCookieValueByName(request, jwtSecurityProps.getCookieStrategy().getCookie());
|
||||
if ( authCookie != null )
|
||||
return authCookie.getValue();
|
||||
|
||||
String authHeader = request.getHeader(jwtSecurityProps.getHeaderStrategy().getHeader());
|
||||
if ( authHeader != null && authHeader.startsWith("Bearer "))
|
||||
return authHeader.substring(7);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getUsernameFromToken(String token) {
|
||||
String username;
|
||||
try {
|
||||
@@ -153,6 +134,22 @@ public class JwtTokenHelper {
|
||||
return refreshedToken;
|
||||
}
|
||||
|
||||
public String retrieveToken(HttpServletRequest request) {
|
||||
if (jwtSecurityProps.getCookieStrategy().isEnabled() == true) {
|
||||
Cookie authCookie = getCookieValueByName(request, jwtSecurityProps.getCookieStrategy().getCookie());
|
||||
if (authCookie != null)
|
||||
return authCookie.getValue();
|
||||
}
|
||||
|
||||
if (jwtSecurityProps.getHeaderStrategy().isEnabled()) {
|
||||
String authHeader = request.getHeader(jwtSecurityProps.getHeaderStrategy().getHeader());
|
||||
if (authHeader != null && authHeader.startsWith("Bearer "))
|
||||
return authHeader.substring(7);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setHeader(HttpServletResponse response, String token) {
|
||||
response.addHeader(jwtSecurityProps.getHeaderStrategy().getHeader(), "Bearer " + token);
|
||||
}
|
||||
|
||||
@@ -6,13 +6,11 @@ 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)
|
||||
//@Component
|
||||
//@ConditionalOnProperty(prefix = "quartz-manager.security.login-model", name = "form-login-enabled", havingValue = "true", matchIfMissing = true)
|
||||
public class AuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler {
|
||||
|
||||
@Override
|
||||
|
||||
@@ -6,18 +6,24 @@ import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
@ConditionalOnProperty(prefix = "quartz-manager.security.login-model", name = "form-login-enabled", havingValue = "true", matchIfMissing = true)
|
||||
//@Component
|
||||
//@ConditionalOnProperty(prefix = "quartz-manager.security.login-model", name = "form-login-enabled", havingValue = "true", matchIfMissing = true)
|
||||
public class AuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler {
|
||||
|
||||
@Autowired
|
||||
private JwtAuthenticationSuccessHandler jwtAuthenticationSuccessHandler;
|
||||
private final JwtAuthenticationSuccessHandler jwtAuthenticationSuccessHandler;
|
||||
|
||||
// @Autowired
|
||||
public AuthenticationSuccessHandler(JwtAuthenticationSuccessHandler jwtAuthenticationSuccessHandler) {
|
||||
super();
|
||||
this.jwtAuthenticationSuccessHandler = jwtAuthenticationSuccessHandler;
|
||||
}
|
||||
|
||||
public String cookieMustBeDeletedAtLogout() {
|
||||
return jwtAuthenticationSuccessHandler.cookieMustBeDeletedAtLogout();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
package it.fabioformosa.quartzmanager.security.auth;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
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;
|
||||
|
||||
String cookieMustBeDeletedAtLogout();
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@ import javax.servlet.http.HttpServletResponse;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.userdetails.User;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
@@ -16,22 +15,34 @@ import it.fabioformosa.quartzmanager.configuration.properties.JwtSecurityPropert
|
||||
import it.fabioformosa.quartzmanager.security.JwtTokenHelper;
|
||||
import it.fabioformosa.quartzmanager.security.model.UserTokenState;
|
||||
|
||||
@Component
|
||||
//@Component
|
||||
public class JwtAuthenticationSuccessHandlerImpl implements JwtAuthenticationSuccessHandler {
|
||||
|
||||
@Autowired
|
||||
private JwtSecurityProperties jwtSecurityProps;
|
||||
// @Autowired
|
||||
private final JwtSecurityProperties jwtSecurityProps;
|
||||
|
||||
private final JwtTokenHelper jwtTokenHelper;
|
||||
|
||||
private final ObjectMapper objectMapper;
|
||||
|
||||
// @Value("${server.servlet.context-path}")
|
||||
private final String contextPath;
|
||||
|
||||
@Autowired
|
||||
public JwtAuthenticationSuccessHandlerImpl(JwtTokenHelper tokenHelper, ObjectMapper objectMapper) {
|
||||
jwtTokenHelper = tokenHelper;
|
||||
public JwtAuthenticationSuccessHandlerImpl(String contextPath, JwtSecurityProperties jwtSecurityProps, JwtTokenHelper jwtTokenHelper, ObjectMapper objectMapper) {
|
||||
this.contextPath = contextPath;
|
||||
this.jwtSecurityProps = jwtSecurityProps;
|
||||
this.jwtTokenHelper = jwtTokenHelper;
|
||||
this.objectMapper = objectMapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String cookieMustBeDeletedAtLogout() {
|
||||
if(!jwtSecurityProps.getCookieStrategy().isEnabled())
|
||||
return null;
|
||||
return jwtSecurityProps.getCookieStrategy().getCookie();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess(Authentication authentication, HttpServletResponse response) throws IOException {
|
||||
User user = (User) authentication.getPrincipal();
|
||||
@@ -42,7 +53,7 @@ public class JwtAuthenticationSuccessHandlerImpl implements JwtAuthenticationSuc
|
||||
Cookie authCookie = new Cookie(jwtSecurityProps.getCookieStrategy().getCookie(), jwtToken);
|
||||
authCookie.setHttpOnly(true);
|
||||
authCookie.setMaxAge((int) jwtSecurityProps.getExpirationInSec());
|
||||
authCookie.setPath("/quartz-manager");
|
||||
authCookie.setPath(contextPath);
|
||||
response.addCookie(authCookie);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
package it.fabioformosa.quartzmanager.security.auth;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
|
||||
import org.springframework.security.web.util.matcher.OrRequestMatcher;
|
||||
import org.springframework.security.web.util.matcher.RequestMatcher;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.filter.OncePerRequestFilter;
|
||||
|
||||
import it.fabioformosa.quartzmanager.security.JwtTokenHelper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
public class JwtTokenAuthenticationFilter extends OncePerRequestFilter {
|
||||
|
||||
public static final String ROOT_MATCHER = "/";
|
||||
public static final String FAVICON_MATCHER = "/favicon.ico";
|
||||
public static final String HTML_MATCHER = "/**/*.html";
|
||||
public static final String CSS_MATCHER = "/**/*.css";
|
||||
public static final String JS_MATCHER = "/**/*.js";
|
||||
public static final String IMG_MATCHER = "/images/*";
|
||||
public static final String LOGIN_MATCHER = "/api/login";
|
||||
public static final String LOGOUT_MATCHER = "/api/logout";
|
||||
|
||||
// private final Log logger = LogFactory.getLog(this.getClass());
|
||||
|
||||
// @Autowired
|
||||
private final JwtTokenHelper jwtTokenHelper;
|
||||
|
||||
// @Autowired
|
||||
private final UserDetailsService userDetailsService;
|
||||
|
||||
private List<String> pathsToSkip = Arrays.asList(
|
||||
ROOT_MATCHER,
|
||||
HTML_MATCHER,
|
||||
FAVICON_MATCHER,
|
||||
CSS_MATCHER,
|
||||
JS_MATCHER,
|
||||
IMG_MATCHER,
|
||||
LOGIN_MATCHER,
|
||||
LOGOUT_MATCHER
|
||||
);
|
||||
|
||||
|
||||
public JwtTokenAuthenticationFilter(JwtTokenHelper jwtTokenHelper, UserDetailsService userDetailsService) {
|
||||
super();
|
||||
this.jwtTokenHelper = jwtTokenHelper;
|
||||
this.userDetailsService = userDetailsService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
|
||||
|
||||
String jwtToken = jwtTokenHelper.retrieveToken(request);
|
||||
if (jwtToken != null && !skipPathRequest(request, pathsToSkip))
|
||||
try {
|
||||
String username = jwtTokenHelper.getUsernameFromToken(jwtToken);
|
||||
UserDetails userDetails = userDetailsService.loadUserByUsername(username);
|
||||
// create authentication
|
||||
JwtTokenBasedAuthentication authentication = new JwtTokenBasedAuthentication(userDetails);
|
||||
authentication.setToken(jwtToken);
|
||||
SecurityContextHolder.getContext().setAuthentication(authentication);
|
||||
} catch (Exception e) {
|
||||
SecurityContextHolder.getContext().setAuthentication(new AnonAuthentication());
|
||||
log.error("Switched to Anonimous Authentication, "
|
||||
+ "because an error occurred setting authentication in security context holder due to " + e.getMessage(), e);
|
||||
}
|
||||
else
|
||||
SecurityContextHolder.getContext().setAuthentication(new AnonAuthentication());
|
||||
|
||||
chain.doFilter(request, response);
|
||||
}
|
||||
|
||||
private boolean skipPathRequest(HttpServletRequest request, List<String> pathsToSkip ) {
|
||||
Assert.notNull(pathsToSkip, "path cannot be null.");
|
||||
List<RequestMatcher> m = pathsToSkip.stream().map(path -> new AntPathRequestMatcher(path)).collect(Collectors.toList());
|
||||
OrRequestMatcher matchers = new OrRequestMatcher(m);
|
||||
return matchers.matches(request);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package it.fabioformosa.quartzmanager.security.auth;
|
||||
|
||||
import org.springframework.security.authentication.AbstractAuthenticationToken;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
|
||||
|
||||
public class JwtTokenBasedAuthentication extends AbstractAuthenticationToken {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private String token;
|
||||
private final UserDetails principle;
|
||||
|
||||
public JwtTokenBasedAuthentication(UserDetails principle) {
|
||||
super(principle.getAuthorities());
|
||||
this.principle = principle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getCredentials() {
|
||||
return token;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserDetails getPrincipal() {
|
||||
return principle;
|
||||
}
|
||||
|
||||
public String getToken() {
|
||||
return token;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAuthenticated() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void setToken( String token ) {
|
||||
this.token = token;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -8,18 +8,20 @@ import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
@Component
|
||||
public class LogoutSuccess implements LogoutSuccessHandler {
|
||||
|
||||
@Autowired
|
||||
private ObjectMapper objectMapper;
|
||||
private final ObjectMapper objectMapper;
|
||||
|
||||
// @Autowired
|
||||
public LogoutSuccess(ObjectMapper objectMapper) {
|
||||
super();
|
||||
this.objectMapper = objectMapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLogoutSuccess(HttpServletRequest httpServletRequest, HttpServletResponse response, Authentication authentication)
|
||||
|
||||
@@ -1,87 +0,0 @@
|
||||
package it.fabioformosa.quartzmanager.security.auth;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
|
||||
import org.springframework.security.web.util.matcher.OrRequestMatcher;
|
||||
import org.springframework.security.web.util.matcher.RequestMatcher;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.filter.OncePerRequestFilter;
|
||||
|
||||
import it.fabioformosa.quartzmanager.security.JwtTokenHelper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
public class TokenAuthenticationFilter extends OncePerRequestFilter {
|
||||
|
||||
public static final String ROOT_MATCHER = "/";
|
||||
public static final String FAVICON_MATCHER = "/favicon.ico";
|
||||
public static final String HTML_MATCHER = "/**/*.html";
|
||||
public static final String CSS_MATCHER = "/**/*.css";
|
||||
public static final String JS_MATCHER = "/**/*.js";
|
||||
public static final String IMG_MATCHER = "/images/*";
|
||||
public static final String LOGIN_MATCHER = "/auth/login";
|
||||
public static final String LOGOUT_MATCHER = "/auth/logout";
|
||||
|
||||
// private final Log logger = LogFactory.getLog(this.getClass());
|
||||
|
||||
@Autowired
|
||||
private JwtTokenHelper tokenHelper;
|
||||
|
||||
@Autowired
|
||||
private UserDetailsService userDetailsService;
|
||||
|
||||
private List<String> pathsToSkip = Arrays.asList(
|
||||
ROOT_MATCHER,
|
||||
HTML_MATCHER,
|
||||
FAVICON_MATCHER,
|
||||
CSS_MATCHER,
|
||||
JS_MATCHER,
|
||||
IMG_MATCHER,
|
||||
LOGIN_MATCHER,
|
||||
LOGOUT_MATCHER
|
||||
);
|
||||
|
||||
@Override
|
||||
public void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
|
||||
|
||||
String authToken = tokenHelper.getToken(request);
|
||||
if (authToken != null && !skipPathRequest(request, pathsToSkip))
|
||||
try {
|
||||
String username = tokenHelper.getUsernameFromToken(authToken);
|
||||
UserDetails userDetails = userDetailsService.loadUserByUsername(username);
|
||||
// create authentication
|
||||
TokenBasedAuthentication authentication = new TokenBasedAuthentication(userDetails);
|
||||
authentication.setToken(authToken);
|
||||
SecurityContextHolder.getContext().setAuthentication(authentication);
|
||||
} catch (Exception e) {
|
||||
SecurityContextHolder.getContext().setAuthentication(new AnonAuthentication());
|
||||
log.error("Switched to Anonimous Authentication, "
|
||||
+ "because an error occurred setting authentication in security context holder due to " + e.getMessage(), e);
|
||||
}
|
||||
else
|
||||
SecurityContextHolder.getContext().setAuthentication(new AnonAuthentication());
|
||||
|
||||
chain.doFilter(request, response);
|
||||
}
|
||||
|
||||
private boolean skipPathRequest(HttpServletRequest request, List<String> pathsToSkip ) {
|
||||
Assert.notNull(pathsToSkip, "path cannot be null.");
|
||||
List<RequestMatcher> m = pathsToSkip.stream().map(path -> new AntPathRequestMatcher(path)).collect(Collectors.toList());
|
||||
OrRequestMatcher matchers = new OrRequestMatcher(m);
|
||||
return matchers.matches(request);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
package it.fabioformosa.quartzmanager.security.auth;
|
||||
|
||||
import org.springframework.security.authentication.AbstractAuthenticationToken;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
|
||||
|
||||
public class TokenBasedAuthentication extends AbstractAuthenticationToken {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private String token;
|
||||
private final UserDetails principle;
|
||||
|
||||
public TokenBasedAuthentication( UserDetails principle ) {
|
||||
super( principle.getAuthorities() );
|
||||
this.principle = principle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getCredentials() {
|
||||
return token;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserDetails getPrincipal() {
|
||||
return principle;
|
||||
}
|
||||
|
||||
public String getToken() {
|
||||
return token;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAuthenticated() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void setToken( String token ) {
|
||||
this.token = token;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -39,7 +39,7 @@ quartz-manager:
|
||||
enabled: true
|
||||
header: "Authorization"
|
||||
cookie-strategy:
|
||||
enabled: true
|
||||
enabled: false
|
||||
cookie: AUTH-TOKEN
|
||||
jobClass: it.fabioformosa.quartzmanager.jobs.myjobs.SampleJob
|
||||
accounts:
|
||||
|
||||
@@ -22,8 +22,14 @@ export class ApiService {
|
||||
'Content-Type': 'application/json'
|
||||
});
|
||||
|
||||
private jwtToken: string;
|
||||
|
||||
constructor( private http: HttpClient) { }
|
||||
|
||||
setToken(token: string) {
|
||||
this.jwtToken = token;
|
||||
}
|
||||
|
||||
get(path: string, args?: any): Observable<any> {
|
||||
const options = {
|
||||
headers: this.headers,
|
||||
@@ -56,6 +62,9 @@ export class ApiService {
|
||||
withCredentials: true
|
||||
});
|
||||
|
||||
if(this.jwtToken)
|
||||
req.headers.append('Authorization', `Bearer ${this.jwtToken}`);
|
||||
|
||||
return this.http.request(req)
|
||||
.pipe(
|
||||
filter(response => response instanceof HttpResponse),
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { HttpHeaders } from '@angular/common/http';
|
||||
import { HttpHeaders, HttpResponse } from '@angular/common/http';
|
||||
import { ApiService } from './api.service';
|
||||
import { UserService } from './user.service';
|
||||
import { ConfigService } from './config.service';
|
||||
import { Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { map, tap } from 'rxjs/operators';
|
||||
|
||||
@Injectable()
|
||||
export class AuthService {
|
||||
@@ -15,16 +15,33 @@ export class AuthService {
|
||||
private config: ConfigService,
|
||||
) { }
|
||||
|
||||
private static extractTokenFromHttpResponse(res: HttpResponse<any>): string {
|
||||
let authorization: string = null;
|
||||
let headers: HttpHeaders = res.headers;
|
||||
if (headers.has('Authorization'))
|
||||
authorization = headers.get('Authorization');
|
||||
if(authorization.startsWith('Bearer '))
|
||||
authorization = authorization.substring(7);
|
||||
return authorization;
|
||||
}
|
||||
|
||||
login(user) {
|
||||
const loginHeaders = new HttpHeaders({
|
||||
'Accept': 'application/json',
|
||||
'Content-Type': 'application/x-www-form-urlencoded'
|
||||
});
|
||||
const body = `username=${user.username}&password=${user.password}`;
|
||||
return this.apiService.post(this.config.login_url, body, loginHeaders).pipe(map(() => {
|
||||
console.log("Login success");
|
||||
this.userService.getMyInfo().subscribe();
|
||||
}));
|
||||
return this.apiService.post(this.config.login_url, body, loginHeaders)
|
||||
.pipe(
|
||||
tap((resp: HttpResponse<any>) => {
|
||||
let jwtToken = AuthService.extractTokenFromHttpResponse(resp);
|
||||
this.apiService.setToken(jwtToken);
|
||||
}),
|
||||
map(() => {
|
||||
console.log("Login success");
|
||||
this.userService.getMyInfo().subscribe();
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
signup(user){
|
||||
@@ -48,4 +65,5 @@ export class AuthService {
|
||||
return this.apiService.post(this.config.change_password_url, passwordChanger);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -82,7 +82,6 @@ export class LoginComponent implements OnInit, OnDestroy {
|
||||
this.authService.login(this.form.value)
|
||||
.pipe(delay(1000))
|
||||
.subscribe(data => {
|
||||
this.userService.getMyInfo().subscribe();
|
||||
this.router.navigate([this.returnUrl]);
|
||||
},
|
||||
error => {
|
||||
|
||||
Reference in New Issue
Block a user