Spring Security - Spring Session

Θα χρησιμοποιήσουμε το Spring Security, για να προστατεύσουμε τα URLS της εφαρμογής και να αυθεντικοποιούμε τους χρήστες. Με το Spring Session θα καταγράφουμε τις συνεδρίες των χρήστων.

Πίνακας users

Ο πίνακας users( id, username, email, password, first_name, last_name, phone, is_active) περιέχει τους χρήστης εφαρμογής. Η εντόλη δημιουργίας του πίνακα δίνεται παρακάτω Users Table

Δημιουργούμε το entity User.

                
                        @Entity
                        @Table(name = "users")
                        public class User{

                           @Id
                           @GeneratedValue(strategy = GenerationType.IDENTITY)
                           @Column(name = "id")
                           private int id;

                           @Column(name = "username")
                           @NotNull(message = "Please provide username")
                           private String username;

                           @Column(name = "username")
                           @Email
                           @NotNull(message = "Please provide email")
                           private String email;

                           @Column(name = "password")
                           @NotNull(message = "Please provide password")
                           private String password;

                           @Column(name = "first_name")
                           @NotNull(message = "Please provide first name")
                           @Size(min = 2, max = 200, message = "first name must be between 2 and 200 characters")
                           private String first_name;

                           @Column(name = "last_name")
                           @NotNull(message = "Please provide last name")
                           @Size(min = 2, max = 200, message = "last name must be between 2 and 200 characters")
                           private String last_name;

                           @Column(name = "phone")
                           @NotNull(
                           private String phone;

                           @Column(name = "is_active")
                           @NotNull(
                           private boolean is_active;

                           public User() {}

                           //Getters - Setters ...

                        } 
                
            
Πίνακας authorities

Ο πίνακας users( id, username, roles) περιέχει τον ρόλο του κάθε χρήστη. Η εντόλη δημιουργίας του πίνακα δίνεται παρακάτω Authoritites Table

Δημιουργούμε το entity Authority.

                
                        @Entity
                        @Table(name = "authorities")
                        public class Authority{

                           @Id
                           @GeneratedValue(strategy = GenerationType.IDENTITY)
                           @Column(name = "id")
                           private int id;

                           @OneToOne(fetch = FetchType.LAZY)
                           @JoinColumn(name = "username", referencedColumnName = "username")
                           private User user;

                           @Column(name = "role")
                           @NotNull(message = "Please provide role type")
                           private String role;

                           public Authority() {}

                           //Getters - Setters ...

                        } 
                
            
Spring Security

Εισάγουμε το ακόλουθο dependency στο pom.xml

                    
                            <dependency>
                                <groupId> org.springframework.boot </groupId>
                                <artifactId< spring-boot-starter-security </artifactId>
                            </dependency>
                    
            

Δημιουργούμε την κλάση configuration SecurityConfiguration στο πακέτο springeshop.configuration

Ενεργοποιούμε το HTTP Basic authentication και το μηχανισμό CRSF. Στέλνεται ένα cookie XSRF-TOKEN στον client, το οποίο στέλνει σε κάθε αίτημα του μετά. Ο χρήστης πρέπει, να είναι σε αυθεντικοποίημενος σε όλα τα URLs, εκτός από τα εξής

                
                             @EnableWebSecurity
                             @Configuration
                             public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

                             @Autowired
                             private DataSource  dataSource;

                             @Override
                             protected void  configure(HttpSecurity http) throws Exception{ 
                               http.anonymous().authorities("ROLE_GUEST").and()
                                 .authorizeRequests()
                                 .antMatchers(HttpMethod.GET, "/*", "/api/**", "/category/**", "/product/**").permitAll()
                                 .antMatchers(HttpMethod.POST, "/api/**").permitAll()
                                 .antMatchers(HttpMethod.GET, "/anonymous/session").permitAll()
                                 .antMatchers(HttpMethod.POST, "/authentication/validateuser").permitAll()
                                 .anyRequest().authenticated()
                                 .and()
                                 .httpBasic()
                                 .and().csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
                             }
                
            

Ενεργοποιούμε το JDBC Authentcation, το οποίο πραγματοποεί το ερώτημα select username, password, is_active from users where username=?, για την αυθεντικοποίηση του χρήστη.

                
                             @Autowired
                             public void  configure(AuthenticationManagerBuilder auth) throws Exception{ 
                               auth.jdbcAuthentication().passwordEncoder(passwordEncoder()).dataSource(dataSource)
                               .usersByUsernameQuery("select username, password, is_active from users where username=?")
                               .authoritiesByUsernameQuery("select username, role from authorities where username=?");
                             }

                             @Bean(name = "passwordEncoder")
                             public BCryptPasswordEncoder  passwordEncoder() {
                               return new BCryptPasswordEncoder();
                             }

                             }
                
            
Spring Session

Εισάγουμε το ακόλουθο dependency στο pom.xml

                        
                                <dependency>
                                    <groupId> org.springframework.session </groupId>
                                    <artifactId< spring-session-jdbc </artifactId>
                                </dependency>
                        
                

Προσθέτουμε τα ακόλουθα properties στο αρχείο application.properties.

                
                            spring.session.store-type=jdbc
                            spring.session.jdbc.initialize-schema=never
                            spring.session.timeout = 6h
                
            

Το Spring Session θα εισάγει αυτόματα τους χρήστες, οι οποίοι έχουν μια ενεργή συνεδρία HTTP και στοιχεία της συνεδρίας τους. Δημιουργούμε τους πίνακες SPRING_SESSION και SPRING_SESSION_ATTRIBUTES. Το ερώτημα δημιουργίας τους δίνεται παρακάτω:

Session Tables
Πηγές