#30 removed all classed moved in quartz-manager-security

This commit is contained in:
fabio.formosa
2021-02-02 23:41:19 +01:00
parent 1f631529d9
commit 8c5b349196
38 changed files with 102 additions and 1844 deletions

View File

@@ -18,8 +18,9 @@
<modules> <modules>
<module>quartz-manager-api</module> <module>quartz-manager-api</module>
<module>quartz-manager-ui-webjar</module> <module>quartz-manager-ui-webjar</module>
<module>quartz-manager-security</module>
<module>quartz-manager-web-showcase</module> <module>quartz-manager-web-showcase</module>
<module>quartz-manager-security</module></modules> </modules>
<dependencyManagement> <dependencyManagement>
<dependencies> <dependencies>
@@ -28,6 +29,16 @@
<artifactId>quartz-manager-api</artifactId> <artifactId>quartz-manager-api</artifactId>
<version>2.2.2-SNAPSHOT</version> <version>2.2.2-SNAPSHOT</version>
</dependency> </dependency>
<dependency>
<groupId>it.fabioformosa.quartz-manager</groupId>
<artifactId>quartz-manager-security</artifactId>
<version>2.2.2-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>it.fabioformosa.quartz-manager</groupId>
<artifactId>quartz-manager-ui-webjar</artifactId>
<version>2.2.2-SNAPSHOT</version>
</dependency>
</dependencies> </dependencies>
</dependencyManagement> </dependencyManagement>

View File

@@ -0,0 +1,82 @@
package it.fabioformosa.quartzmanager.security.controllers;
import java.util.HashMap;
import java.util.Map;
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.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
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.helpers.impl.JwtTokenHelper;
import it.fabioformosa.quartzmanager.security.models.UserTokenState;
import it.fabioformosa.quartzmanager.security.services.impl.CustomUserDetailsService;
/**
* JWT Temporary disabled
*
* @author Fabio.Formosa
*
*/
//@RestController
//@RequestMapping( value = "/api", produces = MediaType.APPLICATION_JSON_VALUE )
public class AuthenticationController {
static class PasswordChanger {
public String oldPassword;
public String newPassword;
}
@Autowired
private CustomUserDetailsService userDetailsService;
@Autowired
JwtTokenHelper tokenHelper;
@Value("${quartz-manager.security.jwt.expiration-in-sec}")
private int EXPIRES_IN_SEC;
@Value("${quartz-manager.security.jwt.cookie-strategy-cookie}")
private String TOKEN_COOKIE;
@RequestMapping(value = "/changePassword", method = RequestMethod.POST)
@PreAuthorize("hasRole('USER')")
public ResponseEntity<?> changePassword(@RequestBody PasswordChanger passwordChanger) {
userDetailsService.changePassword(passwordChanger.oldPassword, passwordChanger.newPassword);
Map<String, String> result = new HashMap<>();
result.put( "result", "success" );
return ResponseEntity.accepted().body(result);
}
@RequestMapping(value = "/refresh", method = RequestMethod.GET)
public ResponseEntity<?> refreshAuthenticationToken(HttpServletRequest request, HttpServletResponse response) {
String authToken = tokenHelper.retrieveToken( request );
if (authToken != null && tokenHelper.canTokenBeRefreshed(authToken)) {
// TODO check user password last update
String refreshedToken = tokenHelper.refreshToken(authToken);
Cookie authCookie = new Cookie( TOKEN_COOKIE, refreshedToken );
authCookie.setPath( "/quartz-manager" );
authCookie.setHttpOnly( true );
authCookie.setMaxAge( EXPIRES_IN_SEC );
// Add cookie to response
response.addCookie( authCookie );
UserTokenState userTokenState = new UserTokenState(refreshedToken, EXPIRES_IN_SEC);
return ResponseEntity.ok(userTokenState);
} else {
UserTokenState userTokenState = new UserTokenState();
return ResponseEntity.accepted().body(userTokenState);
}
}
}

View File

@@ -28,11 +28,14 @@
<groupId>it.fabioformosa.quartz-manager</groupId> <groupId>it.fabioformosa.quartz-manager</groupId>
<artifactId>quartz-manager-api</artifactId> <artifactId>quartz-manager-api</artifactId>
</dependency> </dependency>
<dependency>
<!-- <dependency> --> <groupId>it.fabioformosa.quartz-manager</groupId>
<!-- <groupId>it.fabioformosa.quartz-manager</groupId> --> <artifactId>quartz-manager-ui-webjar</artifactId>
<!-- <artifactId>quartz-manager-ui-webjar</artifactId> --> </dependency>
<!-- </dependency> --> <dependency>
<groupId>it.fabioformosa.quartz-manager</groupId>
<artifactId>quartz-manager-security</artifactId>
</dependency>
<!-- SPRING --> <!-- SPRING -->
<dependency> <dependency>

View File

@@ -1,192 +0,0 @@
package it.fabioformosa.quartzmanager.configuration;
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;
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;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
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.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import com.fasterxml.jackson.databind.ObjectMapper;
import it.fabioformosa.quartzmanager.configuration.properties.InMemoryAccountProperties;
import it.fabioformosa.quartzmanager.configuration.properties.JwtSecurityProperties;
import it.fabioformosa.quartzmanager.security.helpers.LoginConfigurer;
import it.fabioformosa.quartzmanager.security.helpers.impl.AuthenticationFailureHandler;
import it.fabioformosa.quartzmanager.security.helpers.impl.AuthenticationSuccessHandler;
import it.fabioformosa.quartzmanager.security.helpers.impl.FormLoginConfig;
import it.fabioformosa.quartzmanager.security.helpers.impl.JwtAuthenticationSuccessHandler;
import it.fabioformosa.quartzmanager.security.helpers.impl.JwtAuthenticationSuccessHandlerImpl;
import it.fabioformosa.quartzmanager.security.helpers.impl.JwtTokenAuthenticationFilter;
import it.fabioformosa.quartzmanager.security.helpers.impl.JwtTokenHelper;
import it.fabioformosa.quartzmanager.security.helpers.impl.JwtUsernamePasswordFiterLoginConfig;
import it.fabioformosa.quartzmanager.security.helpers.impl.LogoutSuccess;
import it.fabioformosa.quartzmanager.security.helpers.impl.QuartzManagerHttpSecurity;
/**
*
* @author Fabio.Formosa
*
*/
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfigJWT extends WebSecurityConfigurerAdapter {
private static final String[] PATTERNS_SWAGGER_UI = {"/swagger-ui.html", "/v2/api-docs", "/swagger-resources/**", "/webjars/**"};
private static final String LOGIN_PATH = "/quartz-manager/api/login";
private static final String LOGOUT_PATH = "/quartz-manager/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 InMemoryAccountProperties inMemoryAccountProps;
@Override
public void configure(AuthenticationManagerBuilder authenticationManagerBuilder)throws Exception {
configureInMemoryAuthentication(authenticationManagerBuilder);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable() //
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and() //
.exceptionHandling().authenticationEntryPoint(restAuthEntryPoint()).and() //
.addFilterBefore(jwtAuthenticationTokenFilter(), BasicAuthenticationFilter.class) //
.authorizeRequests().anyRequest().authenticated();
QuartzManagerHttpSecurity.from(http).withLoginConfigurer(loginConfigurer(), logoutConfigurer()) //
.login(LOGIN_PATH, authenticationManager()).logout(LOGOUT_PATH);
// temporary disabled csfr
// http.csrf().ignoringAntMatchers("/api/login", "/api/signup") //
// .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()) //
}
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring()//
.antMatchers(HttpMethod.GET, PATTERNS_SWAGGER_UI) //
.antMatchers(HttpMethod.GET,"/css/**", "/js/**", "/img/**", "/lib/**");
}
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
CorsConfigurationSource corsConfigurationSource() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", new CorsConfiguration().applyPermitDefaultValues());
return source;
}
@Bean
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() {
return new JwtTokenHelper(APP_NAME, jwtSecurityProps);
}
@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
@Override
public UserDetailsService userDetailsServiceBean() throws Exception {
return super.userDetailsServiceBean();
}
@Bean
public LoginConfigurer userpwdFilterLoginConfigurer() {
LoginConfigurer loginConfigurer = new JwtUsernamePasswordFiterLoginConfig(jwtAuthenticationSuccessHandler());
return loginConfigurer;
}
// @Bean
// public PasswordEncoder passwordEncoder() {
// return new BCryptPasswordEncoder();
// }
}

View File

@@ -1,24 +0,0 @@
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

@@ -1,33 +0,0 @@
package it.fabioformosa.quartzmanager.configuration.properties;
import lombok.Data;
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 CookieStrategy cookieStrategy;
private HeaderStrategy headerStrategy;
@Data
public static class CookieStrategy {
private boolean enabled;
private String cookie;
}
@Data
public static class HeaderStrategy {
private boolean enabled;
private String header;
}
}

View File

@@ -1,82 +0,0 @@
package it.fabioformosa.quartzmanager.controllers;
import java.util.HashMap;
import java.util.Map;
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.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
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.helpers.impl.JwtTokenHelper;
import it.fabioformosa.quartzmanager.security.model.UserTokenState;
import it.fabioformosa.quartzmanager.security.service.impl.CustomUserDetailsService;
/**
* JWT Temporary disabled
*
* @author Fabio.Formosa
*
*/
//@RestController
//@RequestMapping( value = "/api", produces = MediaType.APPLICATION_JSON_VALUE )
public class AuthenticationController {
static class PasswordChanger {
public String oldPassword;
public String newPassword;
}
@Autowired
private CustomUserDetailsService userDetailsService;
@Autowired
JwtTokenHelper tokenHelper;
@Value("${quartz-manager.security.jwt.expiration-in-sec}")
private int EXPIRES_IN_SEC;
@Value("${quartz-manager.security.jwt.cookie-strategy-cookie}")
private String TOKEN_COOKIE;
@RequestMapping(value = "/changePassword", method = RequestMethod.POST)
@PreAuthorize("hasRole('USER')")
public ResponseEntity<?> changePassword(@RequestBody PasswordChanger passwordChanger) {
userDetailsService.changePassword(passwordChanger.oldPassword, passwordChanger.newPassword);
Map<String, String> result = new HashMap<>();
result.put( "result", "success" );
return ResponseEntity.accepted().body(result);
}
@RequestMapping(value = "/refresh", method = RequestMethod.GET)
public ResponseEntity<?> refreshAuthenticationToken(HttpServletRequest request, HttpServletResponse response) {
String authToken = tokenHelper.retrieveToken( request );
if (authToken != null && tokenHelper.canTokenBeRefreshed(authToken)) {
// TODO check user password last update
String refreshedToken = tokenHelper.refreshToken(authToken);
Cookie authCookie = new Cookie( TOKEN_COOKIE, refreshedToken );
authCookie.setPath( "/quartz-manager" );
authCookie.setHttpOnly( true );
authCookie.setMaxAge( EXPIRES_IN_SEC );
// Add cookie to response
response.addCookie( authCookie );
UserTokenState userTokenState = new UserTokenState(refreshedToken, EXPIRES_IN_SEC);
return ResponseEntity.ok(userTokenState);
} else {
UserTokenState userTokenState = new UserTokenState();
return ResponseEntity.accepted().body(userTokenState);
}
}
}

View File

@@ -1,73 +0,0 @@
package it.fabioformosa.quartzmanager.controllers;
import org.springframework.http.MediaType;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping(value = "/quartz-manager/api", produces = MediaType.APPLICATION_JSON_VALUE)
public class UserController {
/**
* JWT Temporary disabled
*
* @author Fabio.Formosa
*
*/
// @Autowired
// private UserService userService;
// @RequestMapping(method = POST, value = "/signup")
// public ResponseEntity<?> addUser(@RequestBody UserRequest userRequest,
// UriComponentsBuilder ucBuilder) {
//
// User existUser = this.userService.findByUsername(userRequest.getUsername());
// if (existUser != null)
// throw new ResourceConflictException(userRequest.getId(), "Username already exists");
// User user = this.userService.save(userRequest);
// HttpHeaders headers = new HttpHeaders();
// headers.setLocation(ucBuilder.path("/api/user/{userId}").buildAndExpand(user.getId()).toUri());
// return new ResponseEntity<>(user, HttpStatus.CREATED);
// }
//
// @RequestMapping(method = GET, value = "/user/all")
// public List<User> loadAll() {
// return this.userService.findAll();
// }
//
// @RequestMapping(method = GET, value = "/user/{userId}")
// public User loadById(@PathVariable Long userId) {
// return this.userService.findById(userId);
// }
//
//
// @RequestMapping(method = GET, value = "/user/reset-credentials")
// public ResponseEntity<Map> resetCredentials() {
// this.userService.resetCredentials();
// Map<String, String> result = new HashMap<>();
// result.put("result", "success");
// return ResponseEntity.accepted().body(result);
// }
/*
* We are not using userService.findByUsername here(we could), so it is good that we are making
* sure that the user has role "ROLE_USER" to access this endpoint.
*/
// @RequestMapping("/whoami")
// // @PreAuthorize("hasRole('USER')")
// public User user() {
// return (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
// }
@GetMapping("/whoami")
@PreAuthorize("isAuthenticated()")
public Object user() {
return SecurityContextHolder.getContext().getAuthentication().getPrincipal();
}
}

View File

@@ -1,21 +0,0 @@
package it.fabioformosa.quartzmanager.security.helpers;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
/**
* It configures filters to authenticate credentials sent by client or to set authenticationSuccessHandler
*
* Implement this interface for a login strategy
*
*/
public interface LoginConfigurer {
/**
* If the authentication is based on cookie, it returns the name of cookie to be erased at the logout
*/
String cookieMustBeDeletedAtLogout();
HttpSecurity login(String loginPath, HttpSecurity http, AuthenticationManager authenticationManager) throws Exception;
}

View File

@@ -1,55 +0,0 @@
package it.fabioformosa.quartzmanager.security.helpers.impl;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.WebAttributes;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
public class AjaxAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
public class AjaxLoginAuthSuccessHandler extends SimpleUrlAuthenticationSuccessHandler
implements AuthenticationSuccessHandler {
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws IOException, ServletException {
response.setStatus(HttpServletResponse.SC_OK);
clearAuthenticationAttributes(request);
return;
}
}
public AjaxAuthenticationFilter(AuthenticationManager authenticationManager) {
setAuthenticationManager(authenticationManager);
setUsernameParameter("ajaxUsername");
setPasswordParameter("ajaxPassword");
setPostOnly(true);
setFilterProcessesUrl("/ajaxLogin");
setAuthenticationSuccessHandler(new AjaxLoginAuthSuccessHandler());
}
/**
* Removes temporary authentication-related data which may have been stored
* in the session during the authentication process.
*/
protected final void clearAuthenticationAttributes(HttpServletRequest request) {
HttpSession session = request.getSession(false);
if (session == null)
return;
session.removeAttribute(WebAttributes.AUTHENTICATION_EXCEPTION);
}
}

View File

@@ -1,45 +0,0 @@
package it.fabioformosa.quartzmanager.security.helpers.impl;
import org.springframework.security.authentication.AbstractAuthenticationToken;
public class AnonAuthentication extends AbstractAuthenticationToken {
private static final long serialVersionUID = 1L;
public AnonAuthentication() {
super( null );
}
@Override
public boolean equals( Object obj ) {
if ( this == obj )
return true;
if ( obj == null )
return false;
if ( getClass() != obj.getClass() )
return false;
return true;
}
@Override
public Object getCredentials() {
return null;
}
@Override
public Object getPrincipal() {
return null;
}
@Override
public int hashCode() {
int hash = 7;
return hash;
}
@Override
public boolean isAuthenticated() {
return true;
}
}

View File

@@ -1,20 +0,0 @@
package it.fabioformosa.quartzmanager.security.helpers.impl;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
public class AuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler {
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
AuthenticationException exception) throws IOException, ServletException {
super.onAuthenticationFailure(request, response, exception);
}
}

View File

@@ -1,35 +0,0 @@
package it.fabioformosa.quartzmanager.security.helpers.impl;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;
//@Component
//@ConditionalOnProperty(prefix = "quartz-manager.security.login-model", name = "form-login-enabled", havingValue = "true", matchIfMissing = true)
public class AuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler {
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,
Authentication authentication ) throws IOException, ServletException {
clearAuthenticationAttributes(request);
jwtAuthenticationSuccessHandler.onLoginSuccess(authentication, response);
}
}

View File

@@ -1,33 +0,0 @@
package it.fabioformosa.quartzmanager.security.helpers.impl;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
import org.springframework.stereotype.Component;
@Component
public class ComboEntryPoint extends LoginUrlAuthenticationEntryPoint {
private static final String LOGIN_FORM_URL = "/login";
public ComboEntryPoint() {
super(LOGIN_FORM_URL);
}
@Override
public void commence(HttpServletRequest request, HttpServletResponse response,
AuthenticationException authException) throws IOException, ServletException {
if (RESTRequestMatcher.isRestRequest(request)
|| WebsocketRequestMatcher.isWebsocketConnectionRequest(request))
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized");
else
super.commence(request, response, authException);
}
}

View File

@@ -1,75 +0,0 @@
package it.fabioformosa.quartzmanager.security.helpers.impl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configurers.FormLoginConfigurer;
import it.fabioformosa.quartzmanager.security.helpers.LoginConfigurer;
/**
* It delegates form to @FormLoginConfigurer of the httpSecurity.
*
*/
public class FormLoginConfig implements LoginConfigurer {
private static final Logger log = LoggerFactory.getLogger(FormLoginConfig.class);
private final AuthenticationSuccessHandler authenticationSuccessHandler;
private final AuthenticationFailureHandler authenticationFailureHandler;
public FormLoginConfig() {
super();
authenticationSuccessHandler = null;
authenticationFailureHandler = null;
}
public FormLoginConfig(AuthenticationFailureHandler authenticationFailureHandler) {
super();
authenticationSuccessHandler = null;
this.authenticationFailureHandler = authenticationFailureHandler;
}
public FormLoginConfig(AuthenticationSuccessHandler authenticationSuccessHandler) {
super();
this.authenticationSuccessHandler = authenticationSuccessHandler;
authenticationFailureHandler = null;
}
public FormLoginConfig(AuthenticationSuccessHandler authenticationSuccessHandler,
AuthenticationFailureHandler authenticationFailureHandler) {
super();
this.authenticationSuccessHandler = authenticationSuccessHandler;
this.authenticationFailureHandler = authenticationFailureHandler;
}
@Override
public String cookieMustBeDeletedAtLogout() {
return authenticationSuccessHandler.cookieMustBeDeletedAtLogout();
}
@Override
public HttpSecurity login(String loginPath,
HttpSecurity http, AuthenticationManager authenticationManager) throws Exception {
log.debug("Configuring login through FormLoginConfigurer...");
FormLoginConfigurer<HttpSecurity> login = http.formLogin().loginPage(loginPath);
if(authenticationSuccessHandler != null) {
log.debug("Setting an authenticationSuccessHandler");
login = login.successHandler(authenticationSuccessHandler);
}
if(authenticationFailureHandler != null) {
log.debug("Setting an authenticationFailureHandler");
login = login.failureHandler(authenticationFailureHandler);
}
HttpSecurity httpSecurity = login.and();
return httpSecurity;
}
}

View File

@@ -1,34 +0,0 @@
package it.fabioformosa.quartzmanager.security.helpers.impl;
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.web.authentication.UsernamePasswordAuthenticationFilter;
import lombok.SneakyThrows;
/**
* It extends the @UsernamePasswordAuthenticationFilter and it overrides the successfulAuthentication method to put jwtToken in the response
*
*/
public class JwtAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
private JwtAuthenticationSuccessHandler jwtAuthenticationSuccessHandler;
public JwtAuthenticationFilter(AuthenticationManager authenticationManager, JwtAuthenticationSuccessHandler jwtAuthenticationSuccessHandler) {
this.jwtAuthenticationSuccessHandler = jwtAuthenticationSuccessHandler;
setAuthenticationManager(authenticationManager);
}
@SneakyThrows
@Override
protected void successfulAuthentication(HttpServletRequest req,
HttpServletResponse res,
FilterChain chain,
Authentication auth) {
jwtAuthenticationSuccessHandler.onLoginSuccess(auth, res);
}
}

View File

@@ -1,14 +0,0 @@
package it.fabioformosa.quartzmanager.security.helpers.impl;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.core.Authentication;
public interface JwtAuthenticationSuccessHandler {
String cookieMustBeDeletedAtLogout();
void onLoginSuccess(Authentication authentication, HttpServletResponse response) throws IOException;
}

View File

@@ -1,78 +0,0 @@
package it.fabioformosa.quartzmanager.security.helpers.impl;
import java.io.IOException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.User;
import com.fasterxml.jackson.databind.ObjectMapper;
import it.fabioformosa.quartzmanager.configuration.properties.JwtSecurityProperties;
import it.fabioformosa.quartzmanager.security.model.UserTokenState;
/**
* It depends on @JwtTokenHelper to generate the jwtToken.
* On login success, it generates the jwtToken and it returns it to the login according to possible strategies: cookie, response header.
* You can choice the strategy through @JwtSecurityProperties
*
*/
public class JwtAuthenticationSuccessHandlerImpl implements JwtAuthenticationSuccessHandler {
private static final Logger log = LoggerFactory.getLogger(JwtAuthenticationSuccessHandlerImpl.class);
private final JwtSecurityProperties jwtSecurityProps;
private final JwtTokenHelper jwtTokenHelper;
private final ObjectMapper objectMapper;
private final String contextPath;
@Autowired
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 onLoginSuccess(Authentication authentication, HttpServletResponse response) throws IOException {
log.debug("Login successed, generating jwtToken...");
User user = (User) authentication.getPrincipal();
String jwtToken = jwtTokenHelper.generateToken(user.getUsername());
if(jwtSecurityProps.getCookieStrategy().isEnabled()) {
Cookie authCookie = new Cookie(jwtSecurityProps.getCookieStrategy().getCookie(), jwtToken);
authCookie.setHttpOnly(true);
authCookie.setMaxAge((int) jwtSecurityProps.getExpirationInSec());
authCookie.setPath(contextPath);
response.addCookie(authCookie);
log.debug("Set jwtToken into the cookie {}", jwtSecurityProps.getCookieStrategy().getCookie());
}
if(jwtSecurityProps.getHeaderStrategy().isEnabled()) {
jwtTokenHelper.setHeader(response, jwtToken);
log.debug("Set jwtToken into the response header {}", jwtSecurityProps.getHeaderStrategy().getHeader());
}
UserTokenState userTokenState = new UserTokenState(jwtToken, jwtSecurityProps.getExpirationInSec());
String jwtResponse = objectMapper.writeValueAsString(userTokenState);
response.setContentType("application/json");
response.getWriter().write(jwtResponse);
}
}

View File

@@ -1,105 +0,0 @@
package it.fabioformosa.quartzmanager.security.helpers.impl;
import java.io.IOException;
import java.util.ArrayList;
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.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.web.filter.OncePerRequestFilter;
/**
* It finds the jwtToken into the request, it validates it and sets an @Authentication into the @SecurityContextHolder.
* If the request has a path included into the paths that must be skipped, it sets an anonymous authentication
*
* It delegates the jwtToken retrieve to the @JwtTokenHelper that applies several strategies.
*
*/
public class JwtTokenAuthenticationFilter extends OncePerRequestFilter {
private static final Logger log = LoggerFactory.getLogger(JwtTokenAuthenticationFilter.class);
private static final String ROOT_MATCHER = "/";
private static final String FAVICON_MATCHER = "/favicon.ico";
private static final String HTML_MATCHER = "/**/*.html";
private static final String CSS_MATCHER = "/**/*.css";
private static final String JS_MATCHER = "/**/*.js";
private static final String IMG_MATCHER = "/images/*";
private static final String LOGIN_MATCHER = "/api/login";
private static final String LOGOUT_MATCHER = "/api/logout";
private static List<String> PATH_TO_SKIP = Arrays.asList(
ROOT_MATCHER,
HTML_MATCHER,
FAVICON_MATCHER,
CSS_MATCHER,
JS_MATCHER,
IMG_MATCHER,
LOGIN_MATCHER,
LOGOUT_MATCHER
);
private final JwtTokenHelper jwtTokenHelper;
private final UserDetailsService userDetailsService;
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) {
log.debug("Found a jwtToken into the request {}", request.getPathInfo());
try {
String username = jwtTokenHelper.getUsernameFromToken(jwtToken);
UserDetails userDetails = userDetailsService.loadUserByUsername(username);
JwtTokenBasedAuthentication authentication = new JwtTokenBasedAuthentication(userDetails);
authentication.setToken(jwtToken);
SecurityContextHolder.getContext().setAuthentication(authentication);
} catch (Exception e) {
log.error("Authentication failed! an expected error occurred authenticating the request {}", request.getRequestURL());
// SecurityContextHolder.getContext().setAuthentication(new AnonAuthentication());
// log.error("Switched to Anonymous Authentication, "
// + "because an error occurred setting authentication in security context holder due to " + e.getMessage(), e);
}
}
else if(skipPathRequest(request, PATH_TO_SKIP)) {
log.debug("Detected a path to be skipped from authentication, so activated anonymous auth for {}", request.getRequestURL());
SecurityContextHolder.getContext().setAuthentication(new AnonAuthentication());
}
else
log.debug("Not found any jwtToken and the request hasn't a path to be skipped from auth. Path: {}", request.getRequestURL());
chain.doFilter(request, response);
}
private boolean skipPathRequest(HttpServletRequest request, List<String> pathsToSkip ) {
if(pathsToSkip == null)
pathsToSkip = new ArrayList<String>();
List<RequestMatcher> matchers = pathsToSkip.stream().map(path -> new AntPathRequestMatcher(path)).collect(Collectors.toList());
OrRequestMatcher compositeMatchers = new OrRequestMatcher(matchers);
return compositeMatchers.matches(request);
}
}

View File

@@ -1,42 +0,0 @@
package it.fabioformosa.quartzmanager.security.helpers.impl;
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;
}
}

View File

@@ -1,163 +0,0 @@
package it.fabioformosa.quartzmanager.security.helpers.impl;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.time.ZoneId;
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.slf4j.Logger;
import org.slf4j.LoggerFactory;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import it.fabioformosa.quartzmanager.configuration.properties.JwtSecurityProperties;
/**
*
* @author Fabio.Formosa
*
*/
public class JwtTokenHelper {
private static final Logger log = LoggerFactory.getLogger(JwtTokenHelper.class);
private static String base64EncodeSecretKey(String secretKey) {
return Base64.getEncoder().encodeToString(secretKey.getBytes(StandardCharsets.UTF_8));
}
// @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();
// String username = getUsernameFromToken(token);
// UserDetails userDetails = userDetailsService.loadUserByUsername(username);
return expirationDate.compareTo(generateCurrentDate()) > 0;
} catch (Exception e) {
return false;
}
}
private Date generateCurrentDate() {
return new Date(getCurrentTimeMillis());
}
private Date generateExpirationDate() {
return new Date(getCurrentTimeMillis() + jwtSecurityProps.getExpirationInSec() * 1000);
}
private String generateToken(Map<String, Object> claims) {
return Jwts.builder().setClaims(claims).setExpiration(generateExpirationDate())
.signWith(SIGNATURE_ALGORITHM, base64EncodeSecretKey(jwtSecurityProps.getSecret())).compact();
}
public String generateToken(String username) {
return Jwts.builder().setIssuer(appName).setSubject(username).setIssuedAt(generateCurrentDate())
.setExpiration(generateExpirationDate())
.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();
} catch (Exception e) {
claims = null;
log.error("Error getting claims from jwt token due to " + e.getMessage(), e);
}
return claims;
}
/**
* Find a specific HTTP cookie in a request.
*
* @param request
* The HTTP request object.
* @param name
* The cookie name to look for.
* @return The cookie, or <code>null</code> if not found.
*/
public Cookie getCookieValueByName(HttpServletRequest request, String name) {
if (request.getCookies() == null)
return null;
for (int i = 0; i < request.getCookies().length; i++)
if (request.getCookies()[i].getName().equals(name))
return request.getCookies()[i];
return null;
}
private long getCurrentTimeMillis() {
return LocalDateTime.now().atZone(ZoneId.of("Europe/Rome")).toInstant().toEpochMilli();
}
public String getUsernameFromToken(String token) {
String username;
try {
final Claims claims = getClaimsFromToken(token);
username = claims.getSubject();
} catch (Exception e) {
username = null;
log.error("Error getting claims from jwt token due to " + e.getMessage(), e);
throw e;
}
return username;
}
public String refreshToken(String token) {
String refreshedToken;
try {
final Claims claims = getClaimsFromToken(token);
claims.setIssuedAt(generateCurrentDate());
refreshedToken = generateToken(claims);
} catch (Exception e) {
log.error("Error refreshing jwt token due to " + e.getMessage(), e);
refreshedToken = null;
}
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);
}
if(request.getParameter("access_token") != null)
return request.getParameter("access_token");
return null;
}
public void setHeader(HttpServletResponse response, String token) {
response.addHeader(jwtSecurityProps.getHeaderStrategy().getHeader(), "Bearer " + token);
}
}

View File

@@ -1,46 +0,0 @@
package it.fabioformosa.quartzmanager.security.helpers.impl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.web.filter.GenericFilterBean;
import it.fabioformosa.quartzmanager.security.helpers.LoginConfigurer;
/**
* It adds a new filter @JwtAuthenticationFilter after @AbstractPreAuthenticatedProcessingFilter that match login path
*
*/
public class JwtUsernamePasswordFiterLoginConfig implements LoginConfigurer {
private static final Logger log = LoggerFactory.getLogger(JwtUsernamePasswordFiterLoginConfig.class);
private final JwtAuthenticationSuccessHandler jwtAuthenticationSuccessHandler;
public JwtUsernamePasswordFiterLoginConfig(JwtAuthenticationSuccessHandler jwtAuthenticationSuccessHandler) {
super();
this.jwtAuthenticationSuccessHandler = jwtAuthenticationSuccessHandler;
}
public GenericFilterBean authenticationProcessingFilter(String loginPath, AuthenticationManager authenticationManager) throws Exception {
JwtAuthenticationFilter authenticationProcessingFilter = new JwtAuthenticationFilter(authenticationManager, jwtAuthenticationSuccessHandler);
authenticationProcessingFilter.setRequiresAuthenticationRequestMatcher(new RegexRequestMatcher(loginPath, HttpMethod.POST.name(), false));
return authenticationProcessingFilter;
}
@Override
public String cookieMustBeDeletedAtLogout() {
return jwtAuthenticationSuccessHandler.cookieMustBeDeletedAtLogout();
}
@Override
public HttpSecurity login(String loginPath, HttpSecurity http, AuthenticationManager authenticationManager) throws Exception {
log.debug("Configuring login through JwtAuthenticationFilter...");
return http.addFilterAfter(authenticationProcessingFilter(loginPath, authenticationManager), AbstractPreAuthenticatedProcessingFilter.class);
}
}

View File

@@ -1,36 +0,0 @@
package it.fabioformosa.quartzmanager.security.helpers.impl;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
import com.fasterxml.jackson.databind.ObjectMapper;
public class LogoutSuccess implements LogoutSuccessHandler {
private final ObjectMapper objectMapper;
public LogoutSuccess(ObjectMapper objectMapper) {
super();
this.objectMapper = objectMapper;
}
@Override
public void onLogoutSuccess(HttpServletRequest httpServletRequest, HttpServletResponse response, Authentication authentication)
throws IOException, ServletException {
Map<String, String> result = new HashMap<>();
result.put( "result", "success" );
response.setContentType("application/json");
response.getWriter().write(objectMapper.writeValueAsString(result));
response.setStatus(HttpServletResponse.SC_OK);
}
}

View File

@@ -1,57 +0,0 @@
package it.fabioformosa.quartzmanager.security.helpers.impl;
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.security.helpers.LoginConfigurer;
/**
* It wraps the httpSecurity to provide new function as login and logout
*
*/
public class QuartzManagerHttpSecurity extends SecurityConfigurerAdapter<DefaultSecurityFilterChain, HttpSecurity> {
public static QuartzManagerHttpSecurity from(HttpSecurity httpSecurity){
QuartzManagerHttpSecurity newInstance = new QuartzManagerHttpSecurity(httpSecurity);
newInstance.setBuilder(httpSecurity);
return newInstance;
}
private HttpSecurity httpSecurity;
private LoginConfigurer loginConfigurer;
private LogoutSuccess logoutSuccess;
public QuartzManagerHttpSecurity(HttpSecurity httpSecurity) {
this.httpSecurity = httpSecurity;
// applicationContext = httpSecurity.getSharedObject(ApplicationContext.class);
}
public QuartzManagerHttpSecurity login(String loginPath, AuthenticationManager authenticationManager) throws Exception {
if(loginConfigurer == null || logoutSuccess == null)
throw new IllegalStateException("QuartzManagerHttpSecurity requires to be set loginConfigurer and logoutSuccess!");
httpSecurity = loginConfigurer.login(loginPath, httpSecurity, authenticationManager);
return this;
}
public LogoutConfigurer<HttpSecurity> logout(String logoutPath) throws Exception {
LogoutConfigurer<HttpSecurity> logoutConfigurer = httpSecurity.logout().logoutRequestMatcher(new AntPathRequestMatcher(logoutPath))
.logoutSuccessHandler(logoutSuccess);
String cookie = loginConfigurer.cookieMustBeDeletedAtLogout();
if(cookie != null)
logoutConfigurer.deleteCookies(cookie);
return logoutConfigurer;
}
public QuartzManagerHttpSecurity withLoginConfigurer(LoginConfigurer loginConfigurer, LogoutSuccess logoutSuccess) {
this.loginConfigurer = loginConfigurer;
this.logoutSuccess = logoutSuccess;
return this;
}
}

View File

@@ -1,26 +0,0 @@
package it.fabioformosa.quartzmanager.security.helpers.impl;
import javax.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.web.util.matcher.ELRequestMatcher;
import org.springframework.security.web.util.matcher.RequestMatcher;
public class RESTRequestMatcher {
static private final Logger log = LoggerFactory.getLogger(RESTRequestMatcher.class);
static public RequestMatcher matcherRequestedWith = new ELRequestMatcher(
"hasHeader('X-Requested-With','XMLHttpRequest')");
static public RequestMatcher matcherAccept = new ELRequestMatcher(
"hasHeader('accept','application/json, text/plain, */*')");
static public boolean isRestRequest(HttpServletRequest request) {
log.trace("Detecting if it's an AJAX Request: " + request.getRequestURL() + " accept: "
+ request.getHeader("accept") + " " + " X-Requested-With: "
+ request.getHeader("X-Requested-With"));
return matcherRequestedWith.matches(request) || matcherAccept.matches(request);
}
}

View File

@@ -1,23 +0,0 @@
package it.fabioformosa.quartzmanager.security.helpers.impl;
import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.stereotype.Component;
@Component
public class RestAuthenticationEntryPoint implements AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest request,
HttpServletResponse response,
AuthenticationException authException) throws IOException {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, authException.getMessage());
}
}

View File

@@ -1,18 +0,0 @@
package it.fabioformosa.quartzmanager.security.helpers.impl;
import javax.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class WebsocketRequestMatcher {
static private final Logger log = LoggerFactory.getLogger(WebsocketRequestMatcher.class);
static public boolean isWebsocketConnectionRequest(HttpServletRequest request) {
log.trace("Detecting if it's a Websocket Connection Request: " + request.getRequestURL());
return request.getServletPath().equals("/progress/info")
|| request.getServletPath().equals("/logs/info");
}
}

View File

@@ -1,53 +0,0 @@
package it.fabioformosa.quartzmanager.security.model;
import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import org.springframework.security.core.GrantedAuthority;
import com.fasterxml.jackson.annotation.JsonIgnore;
/**
* Temporary enabled only inMemoryAuthentication
*
* @author Fabio.Formosa
*
*/
//@Entity
//@Table(name="Authority")
public class Authority implements GrantedAuthority {
@Id
@Column(name="id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
Long id;
@Column(name="name")
String name;
@Override
public String getAuthority() {
return name;
}
@JsonIgnore
public Long getId() {
return id;
}
@JsonIgnore
public String getName() {
return name;
}
public void setId(Long id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
}

View File

@@ -1,133 +0,0 @@
package it.fabioformosa.quartzmanager.security.model;
import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import com.fasterxml.jackson.annotation.JsonIgnore;
/**
* Temporary enabled only inMemoryAuthentication
*
* @author Fabio.Formosa
*
*/
//@Entity
//@Table(name = "USER")
public class User implements UserDetails, Serializable {
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "username")
private String username;
@JsonIgnore
@Column(name = "password")
private String password;
@Column(name = "firstname")
private String firstname;
@Column(name = "lastname")
private String lastname;
@ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinTable(name = "user_authority",
joinColumns = @JoinColumn(name = "user_id", referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(name = "authority_id", referencedColumnName = "id"))
private List<Authority> authorities;
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return authorities;
}
public String getFirstname() {
return firstname;
}
public Long getId() {
return id;
}
public String getLastname() {
return lastname;
}
@Override
public String getPassword() {
return password;
}
@Override
public String getUsername() {
return username;
}
// We can add the below fields in the users table.
// For now, they are hardcoded.
@JsonIgnore
@Override
public boolean isAccountNonExpired() {
return true;
}
@JsonIgnore
@Override
public boolean isAccountNonLocked() {
return true;
}
@JsonIgnore
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@JsonIgnore
@Override
public boolean isEnabled() {
return true;
}
public void setAuthorities(List<Authority> authorities) {
this.authorities = authorities;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}
public void setId(Long id) {
this.id = id;
}
public void setLastname(String lastname) {
this.lastname = lastname;
}
public void setPassword(String password) {
this.password = password;
}
public void setUsername(String username) {
this.username = username;
}
}

View File

@@ -1,56 +0,0 @@
package it.fabioformosa.quartzmanager.security.model;
public class UserRequest {
private Long id;
private String username;
private String password;
private String firstname;
private String lastname;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getFirstname() {
return firstname;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}
public String getLastname() {
return lastname;
}
public void setLastname(String lastname) {
this.lastname = lastname;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
}

View File

@@ -1,32 +0,0 @@
package it.fabioformosa.quartzmanager.security.model;
public class UserTokenState {
private String access_token;
private Long expires_in_sec;
public UserTokenState() {
this.access_token = null;
this.expires_in_sec = null;
}
public UserTokenState(String access_token, long expires_in_sec) {
this.access_token = access_token;
this.expires_in_sec = expires_in_sec;
}
public String getAccess_token() {
return access_token;
}
public Long getExpires_in_sec() {
return expires_in_sec;
}
public void setAccess_token(String access_token) {
this.access_token = access_token;
}
public void setExpires_in_sec(Long expires_in_sec) {
this.expires_in_sec = expires_in_sec;
}
}

View File

@@ -1,13 +0,0 @@
package it.fabioformosa.quartzmanager.security.repository;
/**
* Temporary disabled
*
* @author Fabio
*
*/
//public interface AuthorityRepository extends JpaRepository<Authority, Long> {
// Authority findByName(String name);
//}
public interface AuthorityRepository {
}

View File

@@ -1,11 +0,0 @@
package it.fabioformosa.quartzmanager.security.repository;
import it.fabioformosa.quartzmanager.security.model.User;
public interface UserRepository {
User findByUsername( String username );
}
//public interface UserRepository extends JpaRepository<User, Long> {
// User findByUsername( String username );
//}

View File

@@ -1,13 +0,0 @@
package it.fabioformosa.quartzmanager.security.service;
/**
* temporary disabled
* @author Fabio
*
*/
public interface AuthorityService {
// List<Authority> findById(Long id);
//
// List<Authority> findByname(String name);
}

View File

@@ -1,18 +0,0 @@
package it.fabioformosa.quartzmanager.security.service;
import java.util.List;
import it.fabioformosa.quartzmanager.security.model.User;
import it.fabioformosa.quartzmanager.security.model.UserRequest;
public interface UserService {
List<User> findAll();
User findById(Long id);
User findByUsername(String username);
void resetCredentials();
User save(UserRequest user);
}

View File

@@ -1,33 +0,0 @@
package it.fabioformosa.quartzmanager.security.service.impl;
import it.fabioformosa.quartzmanager.security.service.AuthorityService;
/**
* Temporary disabled
* @author Fabio
*
*/
//@Service
public class AuthorityServiceImpl implements AuthorityService {
// @Autowired
// private AuthorityRepository authorityRepository;
//
// @Override
// public List<Authority> findById(Long id) {
// Authority auth = this.authorityRepository.getOne(id);
// List<Authority> auths = new ArrayList<>();
// auths.add(auth);
// return auths;
// }
//
// @Override
// public List<Authority> findByname(String name) {
// Authority auth = this.authorityRepository.findByName(name);
// List<Authority> auths = new ArrayList<>();
// auths.add(auth);
// return auths;
// }
}

View File

@@ -1,67 +0,0 @@
package it.fabioformosa.quartzmanager.security.service.impl;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import it.fabioformosa.quartzmanager.security.model.User;
import it.fabioformosa.quartzmanager.security.repository.UserRepository;
/**
* Temporary disabled
* @author Fabio
*
*/
//@Service
public class CustomUserDetailsService implements UserDetailsService {
protected final Log LOGGER = LogFactory.getLog(getClass());
@Autowired
private UserRepository userRepository;
@Autowired
private PasswordEncoder passwordEncoder;
@Autowired
private AuthenticationManager authenticationManager;
public void changePassword(String oldPassword, String newPassword) {
// Authentication currentUser = SecurityContextHolder.getContext().getAuthentication();
// String username = currentUser.getName();
//
// if (authenticationManager != null) {
// LOGGER.debug("Re-authenticating user '"+ username + "' for password change request.");
//
// authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, oldPassword));
// } else {
// LOGGER.debug("No authentication manager set. can't change Password!");
//
// return;
// }
//
// LOGGER.debug("Changing password for user '"+ username + "'");
//
// User user = (User) loadUserByUsername(username);
//
// user.setPassword(passwordEncoder.encode(newPassword));
// userRepository.save(user);
}
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userRepository.findByUsername(username);
if (user == null)
throw new UsernameNotFoundException(String.format("No user found with username '%s'.", username));
else
return user;
}
}

View File

@@ -1,79 +0,0 @@
package it.fabioformosa.quartzmanager.security.service.impl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import it.fabioformosa.quartzmanager.security.model.User;
import it.fabioformosa.quartzmanager.security.model.UserRequest;
import it.fabioformosa.quartzmanager.security.repository.UserRepository;
import it.fabioformosa.quartzmanager.security.service.AuthorityService;
import it.fabioformosa.quartzmanager.security.service.UserService;
/**
* Temporary disabled
* @author Fabio
*
*/
//@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserRepository userRepository;
@Autowired
private PasswordEncoder passwordEncoder;
@Autowired
private AuthorityService authService;
@Override
@PreAuthorize("hasRole('ADMIN')")
public List<User> findAll() throws AccessDeniedException {
// List<User> result = userRepository.findAll();
// return result;
return null;
}
@Override
@PreAuthorize("hasRole('ADMIN')")
public User findById(Long id) throws AccessDeniedException {
// User u = userRepository.getOne(id);
// return u;
return null;
}
@Override
// @PreAuthorize("hasRole('USER')")
public User findByUsername(String username) throws UsernameNotFoundException {
User u = userRepository.findByUsername(username);
return u;
}
@Override
public void resetCredentials() {
// List<User> users = userRepository.findAll();
// for (User user : users) {
// user.setPassword(passwordEncoder.encode("123"));
// userRepository.save(user);
// }
}
@Override
public User save(UserRequest userRequest) {
User user = new User();
// user.setUsername(userRequest.getUsername());
// user.setPassword(passwordEncoder.encode(userRequest.getPassword()));
// user.setFirstname(userRequest.getFirstname());
// user.setLastname(userRequest.getLastname());
// List<Authority> auth = authService.findByname("ROLE_USER");
// user.setAuthorities(auth);
// this.userRepository.save(user);
return user;
}
}