Skip to content

Commit e9e78d0

Browse files
committed
Chapter 4. Add registration form, spring security for basic authentication.
1 parent 099cfd1 commit e9e78d0

File tree

10 files changed

+303
-0
lines changed

10 files changed

+303
-0
lines changed

pom.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,10 @@
9999
<groupId>org.springframework.boot</groupId>
100100
<artifactId>spring-boot-starter</artifactId>
101101
</dependency>
102+
<dependency>
103+
<groupId>org.springframework.boot</groupId>
104+
<artifactId>spring-boot-starter-security</artifactId>
105+
</dependency>
102106
</dependencies>
103107

104108
<build>

src/main/java/tacos/User.java

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package tacos;
2+
3+
import lombok.AccessLevel;
4+
import lombok.Data;
5+
import lombok.NoArgsConstructor;
6+
import lombok.RequiredArgsConstructor;
7+
import org.springframework.security.core.GrantedAuthority;
8+
import org.springframework.security.core.authority.SimpleGrantedAuthority;
9+
import org.springframework.security.core.userdetails.UserDetails;
10+
11+
import javax.persistence.Entity;
12+
import javax.persistence.GeneratedValue;
13+
import javax.persistence.GenerationType;
14+
import javax.persistence.Id;
15+
import java.util.Arrays;
16+
import java.util.Collection;
17+
18+
@Entity
19+
@Data
20+
@NoArgsConstructor(access= AccessLevel.PRIVATE, force=true)
21+
@RequiredArgsConstructor
22+
public class User implements UserDetails {
23+
private static final long serialVersionUID = 1L;
24+
25+
@Id
26+
@GeneratedValue(strategy= GenerationType.AUTO)
27+
private Long id;
28+
private final String username;
29+
private final String password;
30+
private final String fullname;
31+
private final String street;
32+
private final String city;
33+
private final String state;
34+
private final String zip;
35+
private final String phoneNumber;
36+
37+
@Override
38+
public Collection<? extends GrantedAuthority> getAuthorities() {
39+
return Arrays.asList(new SimpleGrantedAuthority("ROLE_USER"));
40+
}
41+
@Override
42+
public boolean isAccountNonExpired() {
43+
return true;
44+
}
45+
@Override
46+
public boolean isAccountNonLocked() {
47+
return true;
48+
}
49+
@Override
50+
public boolean isCredentialsNonExpired() {
51+
return true;
52+
}
53+
@Override
54+
public boolean isEnabled() {
55+
return true;
56+
}
57+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package tacos.data;
2+
3+
import org.springframework.data.repository.CrudRepository;
4+
import tacos.User;
5+
6+
public interface UserRepository extends CrudRepository<User, Long> {
7+
User findByUsername(String username);
8+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package tacos.security;
2+
3+
import org.springframework.security.crypto.password.PasswordEncoder;
4+
import org.springframework.stereotype.Controller;
5+
import org.springframework.web.bind.annotation.GetMapping;
6+
import org.springframework.web.bind.annotation.PostMapping;
7+
import org.springframework.web.bind.annotation.RequestMapping;
8+
import tacos.data.UserRepository;
9+
10+
@Controller
11+
@RequestMapping("/register")
12+
public class RegistrationController {
13+
14+
private UserRepository userRepo;
15+
private PasswordEncoder passwordEncoder;
16+
17+
public RegistrationController(
18+
UserRepository userRepo, PasswordEncoder passwordEncoder) {
19+
this.userRepo = userRepo;
20+
this.passwordEncoder = passwordEncoder;
21+
}
22+
23+
@GetMapping
24+
public String registerForm() {
25+
return "registration";
26+
}
27+
28+
@PostMapping
29+
public String processRegistration(RegistrationForm form) {
30+
userRepo.save(form.toUser(passwordEncoder));
31+
return "redirect:/login";
32+
}
33+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package tacos.security;
2+
3+
import lombok.Data;
4+
import org.springframework.security.crypto.password.PasswordEncoder;
5+
import tacos.User;
6+
7+
@Data
8+
public class RegistrationForm {
9+
10+
private String username;
11+
private String password;
12+
private String fullname;
13+
private String street;
14+
private String city;
15+
private String state;
16+
private String zip;
17+
private String phone;
18+
19+
public User toUser(PasswordEncoder passwordEncoder) {
20+
return new User(
21+
username, passwordEncoder.encode(password),
22+
fullname, street, city, state, zip, phone);
23+
}
24+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package tacos.security;
2+
3+
import org.springframework.beans.factory.annotation.Autowired;
4+
import org.springframework.context.annotation.Configuration;
5+
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
6+
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
7+
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
8+
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
9+
10+
import javax.sql.DataSource;
11+
12+
@Configuration
13+
@EnableWebSecurity
14+
public class SecurityConfig extends WebSecurityConfigurerAdapter {
15+
16+
@Autowired
17+
DataSource dataSource;
18+
19+
@Override
20+
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
21+
auth
22+
.jdbcAuthentication()
23+
.dataSource(dataSource)
24+
.usersByUsernameQuery(
25+
"select username, password, enabled from Users " +
26+
"where username=?")
27+
.authoritiesByUsernameQuery(
28+
"select username, authority from UserAuthorities " +
29+
"where username=?")
30+
.passwordEncoder(new BCryptPasswordEncoder(10));
31+
}
32+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package tacos.security;
2+
3+
import org.springframework.beans.factory.annotation.Autowired;
4+
import org.springframework.security.core.userdetails.UserDetails;
5+
import org.springframework.security.core.userdetails.UserDetailsService;
6+
import org.springframework.security.core.userdetails.UsernameNotFoundException;
7+
import org.springframework.stereotype.Service;
8+
import tacos.User;
9+
import tacos.data.UserRepository;
10+
11+
@Service
12+
public class UserRepositoryUserDetailsService
13+
implements UserDetailsService {
14+
private UserRepository userRepo;
15+
@Autowired
16+
public UserRepositoryUserDetailsService(UserRepository userRepo) {
17+
this.userRepo = userRepo;
18+
}
19+
@Override
20+
public UserDetails loadUserByUsername(String username)
21+
throws UsernameNotFoundException {
22+
User user = userRepo.findByUsername(username);
23+
if (user != null) {
24+
return user;
25+
}
26+
throw new UsernameNotFoundException(
27+
"User '" + username + "' not found");
28+
}
29+
}

src/main/resources/data.sql

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
delete from Taco_Order_Tacos;
2+
delete from Taco_Ingredients;
3+
delete from Taco;
4+
delete from Taco_Order;
5+
delete from Ingredient;
6+
delete from USERS;
7+
delete from USERAUTHORITIES;
8+
9+
insert into Ingredient (id, name, type)
10+
values ('FLTO', 'Flour Tortilla', 'WRAP');
11+
insert into Ingredient (id, name, type)
12+
values ('COTO', 'Corn Tortilla', 'WRAP');
13+
insert into Ingredient (id, name, type)
14+
values ('GRBF', 'Ground Beef', 'PROTEIN');
15+
insert into Ingredient (id, name, type)
16+
values ('CARN', 'Carnitas', 'PROTEIN');
17+
insert into Ingredient (id, name, type)
18+
values ('TMTO', 'Diced Tomatoes', 'VEGGIES');
19+
insert into Ingredient (id, name, type)
20+
values ('LETC', 'Lettuce', 'VEGGIES');
21+
insert into Ingredient (id, name, type)
22+
values ('CHED', 'Cheddar', 'CHEESE');
23+
insert into Ingredient (id, name, type)
24+
values ('JACK', 'Monterrey Jack', 'CHEESE');
25+
insert into Ingredient (id, name, type)
26+
values ('SLSA', 'Salsa', 'SAUCE');
27+
insert into Ingredient (id, name, type)
28+
values ('SRCR', 'Sour Cream', 'SAUCE');
29+
insert into Users (username, password, enabled)
30+
values ('user', 'password', true);
31+
insert into USERAUTHORITIES (username, authority)
32+
values ('user', 'ALL');

src/main/resources/schema.sql

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
create table if not exists Ingredient (
2+
id varchar(4) not null,
3+
name varchar(25) not null,
4+
type varchar(10) not null
5+
);
6+
create table if not exists Taco (
7+
id identity,
8+
name varchar(50) not null,
9+
createdAt timestamp not null
10+
);
11+
create table if not exists Taco_Ingredients (
12+
taco bigint not null,
13+
ingredient varchar(4) not null
14+
);
15+
alter table Taco_Ingredients
16+
add foreign key (taco) references Taco(id);
17+
alter table Taco_Ingredients
18+
add foreign key (ingredient) references Ingredient(id);
19+
create table if not exists Taco_Order (
20+
id identity,
21+
deliveryName varchar(50) not null,
22+
deliveryStreet varchar(50) not null,
23+
deliveryCity varchar(50) not null,
24+
deliveryState varchar(2) not null,
25+
deliveryZip varchar(10) not null,
26+
ccNumber varchar(16) not null,
27+
ccExpiration varchar(5) not null,
28+
ccCVV varchar(3) not null,
29+
placedAt timestamp not null
30+
);
31+
create table if not exists Taco_Order_Tacos (
32+
tacoOrder bigint not null,
33+
taco bigint not null
34+
);
35+
alter table Taco_Order_Tacos
36+
add foreign key (tacoOrder) references Taco_Order(id);
37+
alter table Taco_Order_Tacos
38+
add foreign key (taco) references Taco(id);
39+
40+
create table if not exists Users (
41+
username varchar(25) not null,
42+
password varchar(25) not null,
43+
enabled boolean not null
44+
);
45+
46+
create table if not exists UserAuthorities (
47+
username varchar(25) not null,
48+
authority varchar(25) not null
49+
);
50+
51+
alter table UserAuthorities
52+
add foreign key (username) references Users(username);
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<!DOCTYPE html>
2+
<html xmlns="http://www.w3.org/1999/xhtml"
3+
xmlns:th="http://www.thymeleaf.org">
4+
<head>
5+
<title>Taco Cloud</title>
6+
</head>
7+
<body>
8+
<h1>Register</h1>
9+
<img th:src="@{/images/TacoCloud.png}"/>
10+
<form method="POST" th:action="@{/register}" id="registerForm">
11+
<label for="username">Username: </label>
12+
<input type="text" name="username"/><br/>
13+
<label for="password">Password: </label>
14+
<input type="password" name="password"/><br/>
15+
<label for="confirm">Confirm password: </label>
16+
<input type="password" name="confirm"/><br/>
17+
<label for="fullname">Full name: </label>
18+
<input type="text" name="fullname"/><br/>
19+
<label for="street">Street: </label>
20+
<input type="text" name="street"/><br/>
21+
<label for="city">City: </label>
22+
<input type="text" name="city"/><br/>
23+
<label for="state">State: </label>
24+
<input type="text" name="state"/><br/>
25+
<label for="zip">Zip: </label>
26+
<input type="text" name="zip"/><br/>
27+
<label for="phone">Phone: </label>
28+
<input type="text" name="phone"/><br/>
29+
<input type="submit" value="Register"/>
30+
</form>
31+
</body>
32+
</html>

0 commit comments

Comments
 (0)