From cbf8ffce28f324cecaa37568d0b57f5efaaba255 Mon Sep 17 00:00:00 2001 From: OKaluzny Date: Mon, 1 May 2023 12:00:41 +0300 Subject: [PATCH] Added some security changes --- pom.xml | 4 ++ .../demo/config/SpringSecurityConfig.java | 42 ++++++++++++++----- .../demo/domain/Security/Authority.java | 25 +++++++++++ .../kaluzny/demo/domain/Security/User.java | 20 +++++++++ src/main/resources/application.yml | 8 ++-- src/main/resources/init_role_model.sql | 8 ++++ 6 files changed, 92 insertions(+), 15 deletions(-) create mode 100644 src/main/java/com/kaluzny/demo/domain/Security/Authority.java create mode 100644 src/main/java/com/kaluzny/demo/domain/Security/User.java create mode 100644 src/main/resources/init_role_model.sql diff --git a/pom.xml b/pom.xml index b40c625..5c3d99c 100644 --- a/pom.xml +++ b/pom.xml @@ -38,6 +38,10 @@ org.springframework.boot spring-boot-starter-data-rest + + org.springframework.boot + spring-boot-starter-jdbc + org.postgresql diff --git a/src/main/java/com/kaluzny/demo/config/SpringSecurityConfig.java b/src/main/java/com/kaluzny/demo/config/SpringSecurityConfig.java index 3f2a985..0b09068 100644 --- a/src/main/java/com/kaluzny/demo/config/SpringSecurityConfig.java +++ b/src/main/java/com/kaluzny/demo/config/SpringSecurityConfig.java @@ -1,21 +1,38 @@ package com.kaluzny.demo.config; -import org.springframework.context.annotation.Configuration; +import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Bean; import org.springframework.http.HttpMethod; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; -@Configuration +import javax.sql.DataSource; + +@EnableWebSecurity +@RequiredArgsConstructor public class SpringSecurityConfig extends WebSecurityConfigurerAdapter { + private final DataSource dataSource; + + @Bean + public PasswordEncoder encoder() { + return new BCryptPasswordEncoder(); + } + @Override - protected void configure(AuthenticationManagerBuilder auth) throws Exception { + public void configure(AuthenticationManagerBuilder auth) throws Exception { - auth.inMemoryAuthentication() - .withUser("user").password("{noop}user").roles("USER") - .and() - .withUser("admin").password("{noop}admin").roles("USER", "ADMIN"); + auth.jdbcAuthentication() + .dataSource(dataSource) + .passwordEncoder(encoder()) + .usersByUsernameQuery( + "select username, password, enabled from users where username = ?") + .authoritiesByUsernameQuery( + "select username, authority from authorities where username = ?"); } @Override @@ -25,11 +42,14 @@ protected void configure(HttpSecurity http) throws Exception { .httpBasic() .and() .authorizeRequests() - .antMatchers(HttpMethod.GET, "/api/automobiles/**").hasRole("USER") - .antMatchers(HttpMethod.POST, "/api/automobiles").hasRole("ADMIN") - .antMatchers(HttpMethod.PUT, "/api/automobiles/**").hasRole("ADMIN") - .antMatchers(HttpMethod.DELETE, "/api/automobiles/**").hasRole("ADMIN") + .antMatchers(HttpMethod.GET, "/api/automobiles/**").hasAuthority("USER") + .antMatchers(HttpMethod.POST, "/api/automobiles/**").hasAuthority("ADMIN") + .antMatchers(HttpMethod.PUT, "/api/automobiles/**").hasAuthority("ADMIN") + .antMatchers(HttpMethod.DELETE, "/api/automobiles/**").hasAuthority("ADMIN") + .anyRequest().authenticated() + .and() + .csrf().disable() .formLogin().disable(); } diff --git a/src/main/java/com/kaluzny/demo/domain/Security/Authority.java b/src/main/java/com/kaluzny/demo/domain/Security/Authority.java new file mode 100644 index 0000000..fdb33a9 --- /dev/null +++ b/src/main/java/com/kaluzny/demo/domain/Security/Authority.java @@ -0,0 +1,25 @@ +package com.kaluzny.demo.domain.Security; + +import lombok.Data; + +import javax.persistence.*; +import java.io.Serializable; + +@Entity +@Table(name = "authorities") +@Data +public class Authority { + + @EmbeddedId + private AuthorityKey id; +} +@Embeddable +@Data +class AuthorityKey implements Serializable { + + private String authority; + + @ManyToOne(cascade = CascadeType.ALL) + @JoinColumn(name = "username") + private User user; +} \ No newline at end of file diff --git a/src/main/java/com/kaluzny/demo/domain/Security/User.java b/src/main/java/com/kaluzny/demo/domain/Security/User.java new file mode 100644 index 0000000..187f51b --- /dev/null +++ b/src/main/java/com/kaluzny/demo/domain/Security/User.java @@ -0,0 +1,20 @@ +package com.kaluzny.demo.domain.Security; + +import lombok.Data; + +import javax.persistence.*; +import java.util.Set; + +@Entity +@Data +@Table(name = "users") +public class User { + + @Id + private String username; + private String password; + private Boolean enabled; + + @OneToMany(cascade = CascadeType.ALL) + private Set authority; +} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 2d8f09c..20ac8d7 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -3,10 +3,10 @@ spring: profiles: active: development # Security configuration - security: - user: - name: user - password: user + #security: + # user: + # name: user + # password: user # Database datasource: driver-class-name: org.postgresql.Driver diff --git a/src/main/resources/init_role_model.sql b/src/main/resources/init_role_model.sql new file mode 100644 index 0000000..e5ae100 --- /dev/null +++ b/src/main/resources/init_role_model.sql @@ -0,0 +1,8 @@ + +insert into users(username, password, enabled) values ('user', '$2a$12$u4qBGD6cS2YcC2wj6HzGxev.ieU03TrG0My598eL72Vh1hVtxPA9e', true); +insert into users(username, password, enabled) values ('admin', '$2a$12$u4qBGD6cS2YcC2wj6HzGxev.ieU03TrG0My598eL72Vh1hVtxPA9e', true); +-- password = password +-- https://bcrypt-generator.com/ +insert into authorities(username, authority) values ('user', 'USER'); +insert into authorities(username, authority) values ('admin', 'USER'); +insert into authorities(username, authority) values ('admin', 'ADMIN'); \ No newline at end of file