0% found this document useful (0 votes)
28 views15 pages

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
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
28 views15 pages

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
We take content rights seriously. If you suspect this is your content, claim it here.
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