Θα χρησιμοποιήσουμε το Spring Security, για να προστατεύσουμε τα URLS της εφαρμογής και να αυθεντικοποιούμε τους χρήστες. Με το Spring Session θα καταγράφουμε τις συνεδρίες των χρήστων.
Ο πίνακας users( id, username, email, password, first_name, last_name, phone, is_active) περιέχει τους χρήστης εφαρμογής. Η εντόλη δημιουργίας του πίνακα δίνεται παρακάτω
Δημιουργούμε το 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 ...
}
Ο πίνακας users( id, username, roles) περιέχει τον ρόλο του κάθε χρήστη. Η εντόλη δημιουργίας του πίνακα δίνεται παρακάτω
Δημιουργούμε το 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 ...
}
Εισάγουμε το ακόλουθο 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();
}
}
Εισάγουμε το ακόλουθο 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. Το ερώτημα δημιουργίας τους δίνεται παρακάτω: