0% found this document useful (0 votes)
22 views

Annexe TP Spring Security: Step 1

The document provides steps to implement Spring Security in a Spring Boot application. It covers topics like basic authentication, role-based access control, permission-based authorization and customizing the login page. The steps include adding dependencies, configuring security, creating user details, roles and permissions enum classes.

Uploaded by

abdeouahedfanan
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
22 views

Annexe TP Spring Security: Step 1

The document provides steps to implement Spring Security in a Spring Boot application. It covers topics like basic authentication, role-based access control, permission-based authorization and customizing the login page. The steps include adding dependencies, configuring security, creating user details, roles and permissions enum classes.

Uploaded by

abdeouahedfanan
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 15

Annexe TP Spring Security

Step 1
http://start.spring.io
Java version + Dependensies
Create a new package a new java class controller

@RestController
@RequestMapping ("api/v1/students")

public class StudentController {

private static final List<Student> STUDENTS=


Arrays.asList( new Student(1, "Adam"),
new Student(2, "Anna"),
new Student(3, "Adnan")
);

@GetMapping (path="{studentId}")

public Student getStudent (@PathVariable("studentId")


Integer studentId) {

return STUDENTS.stream()
.filter(student ->
studentId.equals(student.getStudentId()))
.findFirst()
.orElseThrow(()-> new IllegalStateException("Student"
+ studentId +"N'existe pas"));
}
}

Create a new java class Student

public class Student {


private final Integer StudentId;
private final String StudentName;

public Student(Integer studentId, String studentName)


{ StudentId = studentId;
StudentName = studentName;
}

public Integer getStudentId() {


return StudentId;
}

public String getStudentName() {


return StudentName;
}
}

Test Step 1: Access localhost:8080/api/v1/students/1

1
Step 2: A form based authentication
Open pom.xml

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

Enable all the imports

Open pom.xml

Relaunche : localhost:8080/api/v1/students/1

Username : user

Password :

Step 3: Form based authentication details


In the login page, click on Inspect > network
Sing in

2
Step 4: Basic Authentication

Create a package security


Create a Java Class, AppSecurityConfig

@Configuration
@EnableWebSecurity

public class AppSecurityConfig extends


WebSecurityConfigurerAdapter{ @Override
protected void configure(HttpSecurity http) throws Exception {

http
.authorizeRequests()
.anyRequest()
.authenticated()
.and()
.httpBasic();
}
}

Restart server (Can’t logout)

Step 5: Postman
Send a GET request to localhost:8080/api/v1/students/1 o
401 unauthorized
Send a GET request to localhost:8080/api/v1/students/1
o Authorization Type Basi Auth login password (200 OK)

3
Step 6: Whitlist some URLs
Go to ressources > statics > create new index.html file
<h1>ssss</h1> Update AppSecurityConfig

o .authorizeRequests()
.antMatchers("/", "index", "/css/*", "/js/*")
.permitAll()
.anyRequest()
.authenticated()
.and()
.httpBasic();

Step 7: In Memory user


Go to ressources > statics > create new index.html file <h1>ssss</h1>

Go to ressources > statics > create new index.html file


<h1>ssss</h1> o Username ‘unique’
o Password ‘encoded’
o Roles
o Authorities
Update AppSecurityConfig

@Overrid
e @Bean
protected UserDetailsService userDetailsService()
{ UserDetails adamUser = User.builder()
.username("Adam")
.password("pwd")
.roles("STUDENT")
.build();
return new InMemoryUserDetailsManager(
adamUser
);
Error

4
Step 8: Password Encoder
Create a new Java class : PasswordConfig

@Configuration

public class PasswordConfig


{ @Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder(10);
}
}
Update AppSecurityConfig

public class AppSecurityConfig extends WebSecurityConfigurerAdapter{


private final PasswordEncoder passwordEncoder;
@Autowired
public AppSecurityConfig(PasswordEncoder passwordEncoder)
{ this.passwordEncoder = passwordEncoder;
}

Update AppSecurityConfig

@Overrid
e @Bean
protected UserDetailsService userDetailsService()
{ UserDetails adamUser = User.builder()
.username("Adam")
.password(passwordEncoder.encode("pwd"))
.roles("STUDENT")
.build();
It works just fine.
Add anchor point to see the passwordEncoder

5
Step 9: Roles & permissions
Chaque Rôle possède des permissions (Read, write, …)
Add a role (update AppSecurityConfig)

UserDetails annaUser = User.builder()


.username("Anna")
.password(passwordEncoder.encode("pwd123"))
.roles("ADMIN")
.build();

Create a new java class Enum : AppUserRoles

public enum AppUserRole {


STUDENT,
ADMIN;
}
Create a new Java Enum AppUserPermission

public enum AppUserPermission {


STUDENT_READ("student:read"),
STUDENT_WRITE("student:write"),
COURSE_READ("course:read"),
COURSE_WRITE("course:write");

private final String permission;

AppUserPermission(String permission) {
this.permission = permission;
}

public String getPermission() {


return permission;
}
}
To link Roles to Permissions, go to pom.xml add a dependency
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>28.1-JRE</version>
</dependency>
Update AppUserRole Enum
public enum AppUserRole {
STUDENT(Sets.newHashSet()),
ADMIN(Sets.newHashSet(COURSE_READ, COURSE_WRITE,
STUDENT_WRITE, STUDENT_READ));

private final Set<AppUserPermission> permissions;

AppUserRole(Set<AppUserPermission> permissions)
{ this.permissions = permissions;
}

public Set<AppUserPermission> getPermissions()


{ return permissions;
}

6
Step 10: Role based auth

Update AppSecurityConfig

.hasRole(AppUserRole.Admin.name())

Step 11: Permission based auth


Update AppSecurityConfig
Add a new user (ROLE ADMIN TRAINEE)
Update AppUserPermission (READ ONLY)
Create a new java Class “StudentManagementController”
@RestController
@RequestMapping("management/api/v1/students")
public class StudentManagementController {

private static final List<Student> STUDENTS= Arrays.asList(


new Student(1, "Adam"),
new Student(2,"Anna"),
new Student(3,"Mouad")

);
@GetMapping
public List<Student> getAllStudent(){
return STUDENTS;
}

@PostMapping
public void registerNewStudent (@RequestBody Student student)
{ System.out.println(student);
}

@DeleteMapping (path="{studentId}")

public void deleteStudent (@PathVariable("studentId")


Integer studentId) {
System.out.println(studentId);
}

@PutMapping (path="{studentId}")

public void updateStudent (@PathVariable("studentId")


Integer studentId,@RequestBody Student student) {
System.out.println(String.format("%s %s",
studentId, student));
}
}
Go to Postman and connect to management/api/v1/students via GET method
Try a POST method to the server > body > raw > JSON
{ "studentName": "Adam"}

7
Try a PUT method to server > body > raw > JSON
Localhost……/students/1

Update AppSecurityConfig
http
.csrf().disable()
Restart a test postman POST and PUT

Step 12: Authority


Update AppSecurityConfig

.antMatchers(HttpMethod.DELETE"/maganement/api/**").hasAuthority(COURSE_WRI
TE.name())
.antMatchers(HttpMethod.POST"/maganement/api/**").hasAuthority(COURSE_WRITE .name())

.antMatchers(HttpMethod.PUT"/maganement/api/**").hasAuthority(COURSE_WRITE.
name())
.antMatchers(HttpMethod.GET"/maganement/api/**").hasAnyRole(AppUserRole.ADM
IN.name(), AppUserRole.ADMINTREENEE.name())
Explore more next session

Step 13: Csrf

8
Step 14: CSRF Config
In postman Install interceptor
coockies Enable coockies capture

9
Delete csrf.disable()
Send a GET request, and Inspect
coockies XSRF-TOKEN and copy the value

Now proceed a POST command, in the header Add


: X-XSRF-TOKEN and past the XSREF Token

Update AppSecConfig by this line, and inspect to see the details


of the class
.csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFal
se())

Step 15: Form Based Authentication

10
Add .formLogin();
Right click, inspection > application > Cookies > JSESSIONID

Step 16: Customizes Login page


Add .loginPage("/login").permitAll();

11
Add new dependency in pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-
thymeleaf</artifactId> </dependency>
Go to ressources and create a new package > templates
o Create a new page >login.html > <h1>Login Page</h1>
Create a new package In the main arborescence > controller
o Create a new java class >
templateController @Controller
@RequestMapping("/")
public class TemplateController
{ @GetMapping ("login")
public String getLoginView() {

return "login";
}
}

Step 17: Dadabase Authentication


Create a new package > auth
Create a java Class > ApplicationUser
o Implements UserDetails
o Implements parameters
o Declare private final fields
o Add to constroctor
o Add return fields
public class ApplicationUser implements UserDetails {

private final List<? extends


GrantedAuthority> grantedAuthorities;
private final String password;
private final String username;
private final Boolean isAccountNonExpired;
private final Boolean isAccountNonLocked;
private final Boolean isCredentialsNonExpired;
private final Boolean isEnabled;

public ApplicationUser(List<? extends


GrantedAuthority> grantedAuthorities,
String password,
String username,
Boolean isAccountNonExpired,
Boolean isAccountNonLocked,
Boolean isCredentialsNonExpired,
Boolean isEnabled) {
this.grantedAuthorities =
grantedAuthorities; this.password =
password; this.username = username;
this.isAccountNonExpired = isAccountNonExpired;
this.isAccountNonLocked = isAccountNonLocked;
this.isCredentialsNonExpired = isCredentialsNonExpired;
this.isEnabled = isEnabled;
}

@Override
public Collection<? extends GrantedAuthority> getAuthorities()
{ return grantedAuthorities;
}

12
@Override
public String getPassword() {
return password;
}

@Override
public String getUsername() {
return username;
}

@Override
public boolean isAccountNonExpired() {
return isAccountNonExpired;
}

@Override
public boolean isAccountNonLocked() {
return isAccountNonLocked;
}

@Override
public boolean isCredentialsNonExpired()
{ return isCredentialsNonExpired;
}

@Override
public boolean isEnabled() {
return isEnabled;
}
}

Create a java Class > ApplicationUserService o


Implements UserDetailsService
o Override loadUserByUsername
@Service
public class ApplicationUserService implements UserDetailsService
{ @Override
public UserDetails loadUserByUsername(String username)
throws UsernameNotFoundException {
return null;

}
}

Create an interface > ApplicationUserDao

o Add line Optional<ApplicationUser>


SelectApplicationUserByUsername(String username);
public interface ApplicationUserDao {
public Optional<ApplicationUser> SelectApplicationUserByUsername
(String username);
}

o Update ApplicationUSerService : public final ApplicationUserDao


>add to contructor
public class ApplicationUserService implements UserDetailsService {

private final ApplicationUserDao applicationUserDao;

public ApplicationUserService(ApplicationUserDao applicationUserDao) {

13
this.applicationUserDao = applicationUserDao;
}

@Override
public UserDetails loadUserByUsername(String username)
throws UsernameNotFoundException {
return applicationUserDao
.SelectApplicationUserByUsername(username)
.orElseThrow(()-> new
UsernameNotFoundException(String.format("Username %s not found",
username)));
}
}
Create a Java Class > FakeApplicationUserDaoService
@Repository("fake")
public class FakeApplicationUserDaoService
implements ApplicationUserDao {

private final PasswordEncoder passwordEncoder;

@Autowired
public FakeApplicationUserDaoService(PasswordEncoder
passwordEncoder) {
this.passwordEncoder = passwordEncoder;
}

@Override
public Optional<ApplicationUser>
SelectApplicationUserByUsername(String username) {
return getApplicationUsers()
.stream()
.filter(applicationUser ->
username.equals(applicationUser.getUsername()))
.findFirst();
}

private List<ApplicationUser> getApplicationUsers() {


List<ApplicationUser> applicationUsers= Lists.newArrayList(

new ApplicationUser("admin", "pwd",


// ADMIN.getGrantedAuthorities(),
true, true, true, true),
new ApplicationUser("yahya", "wd",
// STUDENT.getGrantedAuthorities(),
true, true, true, true)

);
return applicationUsers;
}
}
Update ApplicationUserServer
@Autowired

public ApplicationUserService(@Qualifier("fake")ApplicationUserDao
applicationUserDao) {
this.applicationUserDao = applicationUserDao;
}
Update AppSecurityConfig
o Delete userDetailsService*

14
private final ApplicationUserService applicationUserService;
@Override
protected void configure(AuthenticationManagerBuilder auth)
throws Exception {
auth.authenticationProvider(daoAuthenticationProvider());
}

@Bean

public DaoAuthenticationProvider daoAuthenticationProvider(){


DaoAuthenticationProvider provider=new
DaoAuthenticationProvider();
provider.setPasswordEncoder(passwordEncoder);
provider.setUserDetailsService(applicationUserService);
return provider;
}

15

You might also like