jdk-21 + spring security 6

This commit is contained in:
Anton Romanov 2025-01-28 10:52:34 +04:00
parent faa14b698c
commit f0c683cd39
18 changed files with 118 additions and 155 deletions

View File

@ -1,45 +1,42 @@
plugins { plugins {
id 'java' id 'java'
id 'io.spring.dependency-management' version '1.0.11.RELEASE' id 'org.springframework.boot' version '3.4.2'
id 'org.springframework.boot' version '2.6.4' id 'io.spring.dependency-management' version '1.1.7'
} }
jar { group = 'ru.ulstu'
archivesBaseName = 'seminar' version = '0.0.1-SNAPSHOT'
java {
toolchain {
languageVersion = JavaLanguageVersion.of(21)
}
} }
repositories { repositories {
maven { maven {
url "http://repo.athene.tech/repository/maven-central/" url = uri("http://repo.athene.tech/repository/maven-central/")
allowInsecureProtocol(true) allowInsecureProtocol(true)
} }
} }
sourceCompatibility = 11
targetCompatibility = 11
dependencies { dependencies {
ext { implementation 'org.springframework.boot:spring-boot-starter'
versionSLF4J = '1.7.24' implementation 'org.springframework.boot:spring-boot-starter-web'
versionJetty = '9.3.16.v20170120'
versionJackson = '2.9.4'
versionSwagger = '2.5.0'
}
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-web'
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-jetty' implementation group: 'org.springframework.boot', name: 'spring-boot-starter-jetty'
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-thymeleaf' implementation group: 'org.springframework.boot', name: 'spring-boot-starter-thymeleaf'
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-validation' implementation group: 'org.springframework.boot', name: 'spring-boot-starter-validation'
implementation group: 'org.springframework.boot', name:'spring-boot-starter-data-jpa' implementation group: 'org.springframework.boot', name:'spring-boot-starter-data-jpa'
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-security' implementation group: 'org.springframework.boot', name: 'spring-boot-starter-security'
implementation group: 'org.slf4j', name: 'slf4j-api', version: versionSLF4J implementation group: 'org.slf4j', name: 'slf4j-api'
implementation group: 'nz.net.ultraq.thymeleaf', name: 'thymeleaf-layout-dialect', version: '3.1.0' implementation group: 'nz.net.ultraq.thymeleaf', name: 'thymeleaf-layout-dialect'
implementation group: 'org.thymeleaf.extras', name: 'thymeleaf-extras-springsecurity5' implementation group: 'org.thymeleaf.extras', name: 'thymeleaf-extras-springsecurity6'
implementation group: 'com.h2database', name:'h2' implementation group: 'com.h2database', name:'h2'
implementation group: 'javax.xml.bind', name: 'jaxb-api' implementation group: 'jakarta.xml.bind', name: 'jakarta.xml.bind-api', version: '4.0.2'
implementation group: 'org.javassist', name: 'javassist' implementation group: 'org.javassist', name: 'javassist', version: '3.30.2-GA'
implementation group: 'com.fasterxml.jackson.module', name: 'jackson-module-blackbird'
implementation group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: '2.13.2'
implementation group: 'org.eclipse.jetty', name: 'jetty-servlet', version: versionJetty implementation group: 'org.eclipse.jetty', name: 'jetty-servlets', version: '11.0.24'
implementation group: 'org.webjars', name: 'jquery', version: '3.6.0' implementation group: 'org.webjars', name: 'jquery', version: '3.6.0'
implementation group: 'org.webjars', name: 'bootstrap', version: '4.3.0' implementation group: 'org.webjars', name: 'bootstrap', version: '4.3.0'
@ -48,9 +45,13 @@ dependencies {
implementation group: 'org.webjars', name: 'font-awesome', version: '4.7.0' implementation group: 'org.webjars', name: 'font-awesome', version: '4.7.0'
implementation group: 'org.webjars', name: 'momentjs', version: '2.24.0' implementation group: 'org.webjars', name: 'momentjs', version: '2.24.0'
implementation group: 'org.webjars', name: 'bootstrap-glyphicons', version: 'bdd2cbfba0' implementation group: 'org.webjars', name: 'bootstrap-glyphicons', version: 'bdd2cbfba0'
implementation group: 'org.webjars', name: 'summernote', version: '0.8.10'
testImplementation group: 'org.springframework.boot', name: 'spring-boot-starter-test' testImplementation 'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}
tasks.named('test') {
useJUnitPlatform()
} }

Binary file not shown.

View File

@ -1,6 +1,7 @@
#Mon Dec 28 10:00:20 PST 2015
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip

View File

@ -2,85 +2,46 @@ package ru.ulstu.configuration;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.BeanInitializationException; import org.springframework.context.annotation.Bean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; 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.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.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.config.annotation.web.configurers.HeadersConfigurer;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler; import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
import ru.ulstu.model.UserRoleConstants; import ru.ulstu.model.UserRoleConstants;
import ru.ulstu.user.UserService;
@Configuration @Configuration
@EnableWebSecurity @EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true) @EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter { public class SecurityConfiguration {
private final Logger log = LoggerFactory.getLogger(SecurityConfiguration.class); private final Logger log = LoggerFactory.getLogger(SecurityConfiguration.class);
private final UserService userService; @Bean
private final BCryptPasswordEncoder bCryptPasswordEncoder; public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
private final AuthenticationSuccessHandler authenticationSuccessHandler;
private final LogoutSuccessHandler logoutSuccessHandler;
public SecurityConfiguration(UserService userService,
BCryptPasswordEncoder bCryptPasswordEncoder,
AuthenticationSuccessHandler authenticationSuccessHandler,
LogoutSuccessHandler logoutSuccessHandler) {
this.userService = userService;
this.bCryptPasswordEncoder = bCryptPasswordEncoder;
this.authenticationSuccessHandler = authenticationSuccessHandler;
this.logoutSuccessHandler = logoutSuccessHandler;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
http.headers().frameOptions().disable();
log.debug("Security enabled"); log.debug("Security enabled");
http.authorizeRequests() http
.antMatchers("/").permitAll() .headers(headers -> headers.frameOptions(HeadersConfigurer.FrameOptionsConfig::disable))
.antMatchers("/login", "/index", "/news/**", "/meetings/**", "/files/**", "/docs/**", .csrf(AbstractHttpConfigurer::disable)
"/public/**", "/organizers", "/webjars/**", "/h2-console/*", "/h2-console").permitAll() .authorizeHttpRequests(auth ->
.antMatchers("/swagger-ui.html").hasAuthority(UserRoleConstants.ADMIN) auth.requestMatchers("/").permitAll()
.anyRequest().authenticated() .requestMatchers("/login", "/index", "/news/**", "/meetings/**", "/files/**", "/docs/**",
.and() "/public/**", "/organizers", "/webjars/**", "/h2-console/*", "/h2-console",
.formLogin() "/css/**", "/js/**", "/img/**", "/templates/**", "/webjars/**").permitAll()
.loginPage("/login") .requestMatchers("/swagger-ui.html").hasAuthority(UserRoleConstants.ADMIN)
.anyRequest().authenticated())
.formLogin(form ->
form.loginPage("/login")
.failureUrl("/loginError") .failureUrl("/loginError")
.successHandler(authenticationSuccessHandler) .permitAll())
.permitAll() .logout(logout ->
.and() logout
.logout()
.logoutSuccessHandler(logoutSuccessHandler)
.logoutSuccessUrl(Constants.LOGOUT_URL) .logoutSuccessUrl(Constants.LOGOUT_URL)
.invalidateHttpSession(false) .invalidateHttpSession(false)
.clearAuthentication(true) .clearAuthentication(true)
.deleteCookies(Constants.COOKIES_NAME) .deleteCookies(Constants.COOKIES_NAME)
.permitAll(); .permitAll());
} return http.build();
@Override
public void configure(WebSecurity web) {
web.ignoring()
.antMatchers("/css/**")
.antMatchers("/js/**")
.antMatchers("/img/**")
.antMatchers("/templates/**")
.antMatchers("/webjars/**");
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) {
try {
auth.userDetailsService(userService).passwordEncoder(bCryptPasswordEncoder);
} catch (Exception e) {
throw new BeanInitializationException("Security configuration failed", e);
}
} }
} }

View File

@ -9,8 +9,8 @@ package ru.ulstu.configuration;
import nz.net.ultraq.thymeleaf.layoutdialect.LayoutDialect; import nz.net.ultraq.thymeleaf.layoutdialect.LayoutDialect;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.thymeleaf.extras.springsecurity5.dialect.SpringSecurityDialect; import org.thymeleaf.extras.springsecurity6.dialect.SpringSecurityDialect;
import org.thymeleaf.spring5.SpringTemplateEngine; import org.thymeleaf.spring6.SpringTemplateEngine;
import org.thymeleaf.templateresolver.ITemplateResolver; import org.thymeleaf.templateresolver.ITemplateResolver;
@Configuration @Configuration

View File

@ -1,16 +1,16 @@
package ru.ulstu.meeting; package ru.ulstu.meeting;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Entity;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.Lob;
import jakarta.persistence.OneToOne;
import jakarta.persistence.Transient;
import jakarta.validation.constraints.NotEmpty;
import org.springframework.format.annotation.DateTimeFormat; import org.springframework.format.annotation.DateTimeFormat;
import ru.ulstu.model.BaseEntity; import ru.ulstu.model.BaseEntity;
import ru.ulstu.news.News; import ru.ulstu.news.News;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.Lob;
import javax.persistence.OneToOne;
import javax.persistence.Transient;
import javax.validation.constraints.NotEmpty;
import java.util.Date; import java.util.Date;
@Entity @Entity

View File

@ -6,6 +6,7 @@
package ru.ulstu.meeting; package ru.ulstu.meeting;
import jakarta.validation.Valid;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.security.access.annotation.Secured; import org.springframework.security.access.annotation.Secured;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
@ -20,7 +21,6 @@ import org.springframework.web.bind.annotation.RequestParam;
import ru.ulstu.model.OffsetablePageRequest; import ru.ulstu.model.OffsetablePageRequest;
import ru.ulstu.model.UserRoleConstants; import ru.ulstu.model.UserRoleConstants;
import javax.validation.Valid;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.stream.Collectors; import java.util.stream.Collectors;

View File

@ -1,14 +1,13 @@
package ru.ulstu.meeting; package ru.ulstu.meeting;
import jakarta.transaction.Transactional;
import jakarta.validation.constraints.NotNull;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import ru.ulstu.news.News; import ru.ulstu.news.News;
import ru.ulstu.news.NewsService; import ru.ulstu.news.NewsService;
import javax.transaction.Transactional;
import javax.validation.constraints.NotNull;
@Service @Service
public class MeetingService { public class MeetingService {
private final MeetingRepository meetingRepository; private final MeetingRepository meetingRepository;

View File

@ -1,11 +1,12 @@
package ru.ulstu.model; package ru.ulstu.model;
import javax.persistence.GeneratedValue; import jakarta.persistence.GeneratedValue;
import javax.persistence.GenerationType; import jakarta.persistence.GenerationType;
import javax.persistence.Id; import jakarta.persistence.Id;
import javax.persistence.MappedSuperclass; import jakarta.persistence.MappedSuperclass;
import javax.persistence.Version; import jakarta.persistence.Version;
import javax.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
import java.io.Serializable; import java.io.Serializable;
@MappedSuperclass @MappedSuperclass

View File

@ -1,16 +1,16 @@
package ru.ulstu.model; package ru.ulstu.model;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.JoinTable;
import jakarta.persistence.ManyToMany;
import jakarta.persistence.Table;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Pattern;
import jakarta.validation.constraints.Size;
import ru.ulstu.configuration.Constants; import ru.ulstu.configuration.Constants;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;

View File

@ -1,11 +1,11 @@
package ru.ulstu.model; package ru.ulstu.model;
import javax.persistence.Column; import jakarta.persistence.Column;
import javax.persistence.Entity; import jakarta.persistence.Entity;
import javax.persistence.Id; import jakarta.persistence.Id;
import javax.persistence.Table; import jakarta.persistence.Table;
import javax.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
import javax.validation.constraints.Size; import jakarta.validation.constraints.Size;
@Entity @Entity
@Table(name = "is_user_roles") @Table(name = "is_user_roles")

View File

@ -1,13 +1,14 @@
package ru.ulstu.model; package ru.ulstu.model;
import javax.persistence.Column; import jakarta.persistence.Column;
import javax.persistence.Entity; import jakarta.persistence.Entity;
import javax.persistence.JoinColumn; import jakarta.persistence.JoinColumn;
import javax.persistence.ManyToOne; import jakarta.persistence.ManyToOne;
import javax.persistence.Table; import jakarta.persistence.Table;
import javax.persistence.Temporal; import jakarta.persistence.Temporal;
import javax.persistence.TemporalType; import jakarta.persistence.TemporalType;
import javax.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
import java.util.Date; import java.util.Date;
@Entity @Entity

View File

@ -1,13 +1,13 @@
package ru.ulstu.news; package ru.ulstu.news;
import jakarta.persistence.Entity;
import jakarta.persistence.Lob;
import jakarta.persistence.OneToOne;
import jakarta.validation.constraints.NotEmpty;
import org.springframework.format.annotation.DateTimeFormat; import org.springframework.format.annotation.DateTimeFormat;
import ru.ulstu.meeting.Meeting; import ru.ulstu.meeting.Meeting;
import ru.ulstu.model.BaseEntity; import ru.ulstu.model.BaseEntity;
import javax.persistence.Entity;
import javax.persistence.Lob;
import javax.persistence.OneToOne;
import javax.validation.constraints.NotEmpty;
import java.util.Date; import java.util.Date;
@Entity @Entity

View File

@ -6,6 +6,7 @@
package ru.ulstu.news; package ru.ulstu.news;
import jakarta.validation.Valid;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.security.access.annotation.Secured; import org.springframework.security.access.annotation.Secured;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
@ -20,7 +21,6 @@ import org.springframework.web.bind.annotation.RequestParam;
import ru.ulstu.model.OffsetablePageRequest; import ru.ulstu.model.OffsetablePageRequest;
import ru.ulstu.model.UserRoleConstants; import ru.ulstu.model.UserRoleConstants;
import javax.validation.Valid;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.stream.Collectors; import java.util.stream.Collectors;

View File

@ -1,12 +1,12 @@
package ru.ulstu.news; package ru.ulstu.news;
import jakarta.transaction.Transactional;
import jakarta.validation.constraints.NotNull;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import ru.ulstu.meeting.Meeting; import ru.ulstu.meeting.Meeting;
import javax.transaction.Transactional;
import javax.validation.constraints.NotNull;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;

View File

@ -1,9 +1,8 @@
package ru.ulstu.user; package ru.ulstu.user;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import javax.servlet.http.HttpServletRequest;
public final class IpAddressResolver { public final class IpAddressResolver {
private static final String CLIENT_IP_HEADER = "Client-IP"; private static final String CLIENT_IP_HEADER = "Client-IP";
private static final String FORWARDED_FOR_HEADER = "X-Forwarded-For"; private static final String FORWARDED_FOR_HEADER = "X-Forwarded-For";

View File

@ -1,5 +1,9 @@
package ru.ulstu.user; package ru.ulstu.user;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.security.core.Authentication; import org.springframework.security.core.Authentication;
@ -8,10 +12,6 @@ import org.springframework.security.web.authentication.SavedRequestAwareAuthenti
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import ru.ulstu.configuration.Constants; import ru.ulstu.configuration.Constants;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException; import java.io.IOException;
@Component @Component

View File

@ -1,5 +1,9 @@
package ru.ulstu.user; package ru.ulstu.user;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.security.core.Authentication; import org.springframework.security.core.Authentication;
@ -8,10 +12,6 @@ import org.springframework.security.web.authentication.logout.SimpleUrlLogoutSuc
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import ru.ulstu.configuration.Constants; import ru.ulstu.configuration.Constants;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException; import java.io.IOException;
@Component @Component