Commit 001e3c7f by Patryk Czarnik

konta użytkowników definiowane w bazie danych

parent 1a485376
/* Dodatkowe tabele i widoki na potrzeby konfiguracji jdbcAuthentication,
* czyli przechowywanie użytkowników i haseł w bazie danych.
*/
DROP VIEW IF EXISTS spring_account_roles;
DROP VIEW IF EXISTS spring_accounts;
DROP TABLE IF EXISTS user_roles;
DROP TABLE IF EXISTS users;
CREATE TABLE users (
user_id INTEGER NOT NULL,
username VARCHAR(30) NOT NULL,
password VARCHAR(100) NOT NULL,
first_name VARCHAR(50),
last_name VARCHAR(50),
-- enabled BOOLEAN NOT NULL,
PRIMARY KEY(user_id),
UNIQUE(username)
);
CREATE TABLE user_roles (
user_id INTEGER NOT NULL,
role VARCHAR(20) NOT NULL,
PRIMARY KEY (user_id, role),
FOREIGN KEY (user_id) REFERENCES users(user_id)
);
CREATE VIEW spring_accounts AS
SELECT username, '{noop}' || password AS password, 1 AS enabled
FROM users;
CREATE VIEW spring_account_roles AS
SELECT username, 'ROLE_' || role AS role
FROM user_roles JOIN users USING(user_id);
INSERT INTO users(user_id, username, password, first_name, last_name) VALUES (1, 'adam', 'abc123', 'Adam', 'Abacki');
INSERT INTO users(user_id, username, password, first_name, last_name) VALUES (2, 'bartek', 'abc123', 'Bartosz', 'Borecki');
INSERT INTO users(user_id, username, password, first_name, last_name) VALUES (3, 'damian', 'abc123', 'Damian', 'Domyślny');
INSERT INTO user_roles(user_id, role) VALUES (1, 'manager');
INSERT INTO user_roles(user_id, role) VALUES (1, 'inna_rola');
INSERT INTO user_roles(user_id, role) VALUES (2, 'pomocnik');
-- SELECT * FROM users;
-- SELECT * FROM users LEFT JOIN user_roles USING(user_id);
--
-- SELECT username, password, enabled FROM spring_accounts;
-- SELECT username, role FROM spring_account_roles;
package sklep.security; package sklep.security;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
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.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.ObjectPostProcessor; import org.springframework.security.config.annotation.ObjectPostProcessor;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration; import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
...@@ -12,7 +14,16 @@ import org.springframework.security.web.SecurityFilterChain; ...@@ -12,7 +14,16 @@ import org.springframework.security.web.SecurityFilterChain;
@Configuration @Configuration
public class SecurityConfig { public class SecurityConfig {
@Autowired
private DataSource dataSource;
// W klasie typu Configuration umieszczamy metody, które w wyniku zwracają obiekty, które dla Springa coś specjalnego znaczą.
// Te metody oznaczamy adnotacją @Bean.
// (w ten sposób można też stworzyć "własne" beany, zamiast podejścia z adnotacją @Component)
// Ta metoda służy ogólnej konfiguracji zabezpieczeń aplikacji webowej.
// M.in. podaje się tutaj reguły dostępu, czyli autoryzacje.
// Tutaj też podaje się sposób uwierzytelnienia, np. formLogin.
@Bean @Bean
SecurityFilterChain setHttpSecurity(HttpSecurity httpSecurity) throws Exception { SecurityFilterChain setHttpSecurity(HttpSecurity httpSecurity) throws Exception {
httpSecurity.authorizeHttpRequests() httpSecurity.authorizeHttpRequests()
...@@ -31,6 +42,8 @@ public class SecurityConfig { ...@@ -31,6 +42,8 @@ public class SecurityConfig {
return httpSecurity.build(); return httpSecurity.build();
} }
// W osobnej metodzie określa się źródło wiedzy o użytkownikach: jacy są użytkownicy, jakie mają hasła.
// Są różne rodzaje takich źródeł: inMemory - użytkownicy wpisani na sztywno w kodzie; jdbc - w bazie danych; ldap - w zewnętrznym systemie; można zaimplementować samemu
@Bean @Bean
AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration, ApplicationContext applicationContext) throws Exception { AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration, ApplicationContext applicationContext) throws Exception {
ObjectPostProcessor<Object> objectPostProcessor = new ObjectPostProcessor<Object>() { ObjectPostProcessor<Object> objectPostProcessor = new ObjectPostProcessor<Object>() {
...@@ -40,12 +53,21 @@ public class SecurityConfig { ...@@ -40,12 +53,21 @@ public class SecurityConfig {
}; };
return authenticationConfiguration.authenticationManagerBuilder(objectPostProcessor, applicationContext) return authenticationConfiguration.authenticationManagerBuilder(objectPostProcessor, applicationContext)
.inMemoryAuthentication() .jdbcAuthentication()
.withUser("ala").password("{noop}abc123").roles("manager", "worker").and() .dataSource(dataSource)
.withUser("ola").password("{noop}abc123").roles("worker").and() // mamy podać zapytanie SQL, które pozwoli Springowi odczytać informacje o userze na podstawie nazwy usera
// w wyniku ma zwrócić rekord z trzeba kolumnami: nazwa, hasło, czy aktywny (0/1)
.usersByUsernameQuery("SELECT username, password, enabled FROM spring_accounts WHERE username = ?")
// dla użytkownika zwraca info o uprawnieniach (rolach) danego użytkownika; wynik może składać się z wielu rekordów
.authoritiesByUsernameQuery("SELECT username, role FROM spring_account_roles WHERE username = ?")
.and() .and()
.build(); .build();
} }
} }
/*
.inMemoryAuthentication()
.withUser("ala").password("{noop}abc123").roles("manager", "worker").and()
.withUser("ola").password("{noop}abc123").roles("worker").and()
*/
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment