syllabus…
• Secure Spring Boot REST APIs
• Define users and roles
• Protect URLs based on role
• Store users, passwords and roles in DB (plain-text -> encrypted)
Spring Security Model
• Spring Security defines a framework for security
• Implemented using Servlet filters in the background
• Two methods of securing an app: declarative and programmatic
Spring Security with Servlet Filters
• Servlet Filters are used to pre-process / post-process web requests
• Servlet Filters can route web requests based on security logic
• Spring provides a bulk of security functionality with servlet filters
Spring Security Overview
Spring
Security
Filters
Web
Browser
my app
security
configuration
users
passwords
roles
Protected
Web
Resource
/mytopsecretstuff
Spring Security in Action
Spring
Security
Filters
Spring
Security
Filters
Check if user id and
password are valid
Spring Security in ActiDoones user have
authorized role?
Security Concepts
• Authentication
• Check user id and password with credentials stored in app / db
• Authorization
• Check to see if user has an authorized role
Declarative Security
• Define application’s security constraints in configuration
• All Java config: @Configuration
• Provides separation of concerns between application code and security
Programmatic Security
• Spring Security provides an API for custom application coding
• Provides greater customization for specific app requirements
Enabling Spring Security
1. Edit pom.xml and add spring-boot-starter-security
2.This will automagically secure all endpoints for application
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
Secured Endpoints
• Now when you access your application
• Spring Security will prompt for login
Check console logs
for password
Default user name: user
Spring Security
configuration
• You can override default user name and generated password
File: src/main/resources/application.properties
spring.security.user.name=scott
spring.security.user.password=test123
Authentication and Authorization
• In-memory
• JDBC
• LDAP
• Custom / Pluggable
• others …
users
passwords
roles
We will cover password storage in DB as plain-text AND encrypted
m
Configuring
Basic Security
Our Users
User ID Password Roles
john test123 EMPLOYEE
mary test123 EMPLOYEE, MANAGER
susan test123 EMPLOYEE, MANAGER, ADMIN
We can give ANY
names for user
roles
Development Process
1. Create Spring Security Configuration (@Configuration)
2. Add users, passwords and roles
Step-By-Step
Step 1: Create Spring
Security Configuration
File: DemoSecurityConfig.java
import org.springframework.context.annotation.Configuration;
@Configuration
public class DemoSecurityConfig {
// add our security configurations here …
}
Spring Security Password Storage
• In Spring Security, passwords are stored using a specific format
{id}encodedPassword
ID
Description
noop Plain text passwords
bcrypt BCrypt password hashing
… …
Password Example
{noop}test123
Let’s Spring Security
know the passwords are
stored as plain text (noop)
The encoding
algorithm id
The password
Step 2: Add users, passwords and roles
"ADMIN")
UserDetails susan = User.builder()
.username("susan")
.password("{noop}test123")
.roles("EMPLOYEE",
"MANAGER",
.build();
return new InMemoryUserDetailsManager(john, mary, susan);
}
}
File: DemoSecurityConfig.java
@Configuration
public class DemoSecurityConfig {
@Bean
public InMemoryUserDetailsManager userDetailsManager() {
UserDetails john = User.builder()
.username("john")
.password("{noop}test123")
.roles("EMPLOYEE")
.build();
UserDetails mary = User.builder()
.username("mary")
.password("{noop}test123")
.roles("EMPLOYEE", "MANAGER")
.build();
We will add DB support in
later videos
(plaintext and encrypted)
m
Restrict Access Based on
Roles
Our Example
HTTP Method Endpoint CRUD Action Role
GET /api/employees Read all EMPLOYEE
GET /api/employees/{employeeId} Read single EMPLOYEE
POST /api/employees Create MANAGER
PUT /api/employees Update MANAGER
DELETE /api/employees/{employeeId} Delete employee ADMIN
Restricting Access to
Roles
• General Syntax
requestMatchers(<< add path to match on >>)
.hasRole(<< authorized role >>)
Single role “ADMIN”
Restrict access to a
given path
“/api/employees”
Restricting Access to
Roles
requestMatchers(<< add HTTP METHOD to match on >>, << add path to match on >>)
.hasRole(<< authorized roles >>)
Specify HTTP method:
GET, POST, PUT, DELETE …
Single role
Restrict access to a
given path
“/api/employees”
Restricting Access to
Roles
requestMatchers(<< add HTTP METHOD to match on >>, << add path to match on >>)
.hasAnyRole(<< list of authorized roles >>)
Comma-delimited list
Any role
Authorize Requests for EMPLOYEE role
requestMatchers(HttpMethod.GET,
requestMatchers(HttpMethod.GET,
"/api/employees").hasRole("EMPLOYEE")
"/api/employees/**").hasRole("EMPLOYEE")
The ** syntax:
match on all sub-paths
Authorize Requests for MANAGER role
"/api/employees").hasRole("MANAGER")
requestMatchers(HttpMethod.POST,
requestMatchers(HttpMethod.PUT, "/api/employees").hasRole("MANAGER")
Authorize Requests for ADMIN role
requestMatchers(HttpMethod.DELETE, "/api/employees/**").hasRole("ADMIN")
Pull It Together
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests(configurer ->
configurer
.requestMatchers(HttpMethod.GET,
.requestMatchers(HttpMethod.GET,
.requestMatchers(HttpMethod.POST,
.requestMatchers(HttpMethod.PUT,
"/api/employees").hasRole("EMPLOYEE")
"/api/employees/**").hasRole("EMPLOYEE")
"/api/employees").hasRole("MANAGER")
"/api/employees").hasRole("MANAGER")
.requestMatchers(HttpMethod.DELETE, "/api/employees/**").hasRole("ADMIN"));
// use HTTP Basic authentication
http.httpBasic(Customizer.withDefaults());
return http.build();
}
Use HTTP Basic
Authentication
Cross-Site Request Forgery (CSRF)
• Spring Security can protect against CSRF attacks
• Embed additional authentication data/token into all HTML
forms
• On subsequent requests, web app will verify token before processing
• Primary use case is traditional web applications (HTML forms etc …)
When to use CSRF Protection?
• The Spring Security team recommends
• Use CSRF protection for any normal browser web requests
• Traditional web apps with HTML forms to add/modify data
• If you are building a REST API for non-browser clients
• you may want to disable CSRF protection
• In general, not required for stateless REST APIs
• That use POST, PUT, DELETE and/or PATCH
Pull It Together
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests(configurer ->
configurer
.requestMatchers(HttpMethod.GET,
.requestMatchers(HttpMethod.GET,
.requestMatchers(HttpMethod.POST,
.requestMatchers(HttpMethod.PUT,
"/api/employees").hasRole("EMPLOYEE")
"/api/employees/**").hasRole("EMPLOYEE")
"/api/employees").hasRole("MANAGER")
"/api/employees").hasRole("MANAGER")
.requestMatchers(HttpMethod.DELETE, "/api/employees/**").hasRole("ADMIN"));
// use HTTP Basic authentication
http.httpBasic(Customizer.withDefaults());
// disable Cross Site Request Forgery (CSRF)
http.csrf(csrf -> csrf.disable());
return http.build();
}
In general, CSRF is not required for
stateless REST APIs that use
POST, PUT, DELETE and/or PATCH
Database Access
• So far, our user accounts were hard coded in Java source code
• We want to add database access Advanced
Recall Our User Roles
User ID Password Roles
john test123 EMPLOYEE
mary test123 EMPLOYEE, MANAGER
susan test123 EMPLOYEE, MANAGER, ADMIN
Database Support in Spring
Security
• Spring Security can read user account info from database
• By default, you have to follow Spring Security’s predefined table schemas
Spring
Security
JDBC
Code
Out-of-the-box
Customize Database Access
with Spring Security
• Can also customize the table schemas
• Useful if you have custom tables specific to your project / custom
• You will be responsible for developing the code to access the data
• JDBC, JPA/Hibernate etc …
Database Support in Spring
Security
• Follow Spring Security’s predefined table schemas
Spring
Security
JDBC
Code
Out-of-the-box
Development Process
1. Develop SQL Script to set up database tables
2. Add database support to Maven POM file
3.Create JDBC properties file
4. Update Spring Security Configuration to use
JDBC
Step-By-Step
Default Spring Security
Database Schema
“authorities” same as
“roles”
Step 1: Develop SQL Script to setup database tables
CREATE TABLE `users` (
`username` varchar(50) NOT NULL,
`password` varchar(50) NOT NULL,
`enabled` tinyint NOT NULL,
PRIMARY KEY (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Step 1: Develop SQL Script to setup database tables
Let’s Spring Security know the
passwords are stored as plain text
(noop)
The encoding algorithm id
The password
INSERT INTO `users`
VALUES
('john','{noop}test
123',1),
('mary','{noop}test
123',1),
('susan','{noop}tes
t123',1);
Step 1: Develop SQL Script to setup database tables
CREATE TABLE `authorities` (
`username` varchar(50) NOT NULL,
`authority` varchar(50) NOT NULL,
UNIQUE KEY `authorities_idx_1` (`username`,`authority`),
CONSTRAINT `authorities_ibfk_1`
FOREIGN KEY (`username`)
REFERENCES `users` (`username`)
) ENGINE=InnoDB DEFAULT
CHARSET=latin1;
Step 1: Develop SQL Script to setup database tables
“authorities” same as
“roles”
INSERT INTO `authorities`
VALUES
('john','ROLE_EMPLOYEE'),
('mary','ROLE_EMPLOYEE'),
('mary','ROLE_MANAGER'),
('susan','ROLE_EMPLOYEE')
,
('susan','ROLE_MANAGER'),
('susan','ROLE_ADMIN');
Internally Spring Security
uses “ROLE_” prefix
Step 2: Add Database Support to Maven POM file
<!-- MySQL -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
JDBC Driver
Step 3: Create JDBC Properties File
File: application.properties
#
# JDBC connection properties
#
spring.datasource.url=jdbc:mysql://localhost:3306/employee_directory
spring.datasource.username=springstudent
spring.datasource.password=springstudent
Step 4: Update Spring
Security to use JDBC
@Configuration
public class DemoSecurityConfig {
@Bean
public UserDetailsManager userDetailsManager(DataSource dataSource) {
return new JdbcUserDetailsManager(dataSource);
}
…
}
Inject data source
Auto-configured by Spring Boot
Tell Spring Security to use
JDBC authentication
with our data source
No longer
hard-coding users :-)
luv2code LLC
m
Spring Security Password
Encryption
Password Storage
• So far, our user passwords are stored in plaintext … yikes!
• Ok for getting started … but not for production / real-time project :-(
Password Storage - Best Practice
• The best practice is store passwords in an encrypted format
Best Practice
Encrypted version of password
Spring Security Team Recommendation
luv2code LLC
• Spring Security recommends using the popular bcrypt algorithm
• bcrypt
• Performs one-way encrypted hashing
• Adds a random salt to the password for additional protection
• Includes support to defeat brute force attacks
How to Get a Bcrypt password
luv2code LLC
You have a plaintext password and you want to encrypt using bcrypt
• Option 1: Use a website utility to perform the encryption
• Option 2: Write Java code to perform the encryption
Spring Security Login Process
1. Retrieve password from db for the user
2. Read the encoding algorithm id (bcrypt etc)
3. For case of bcrypt, encrypt plaintext password from login form (using salt from db password)
4. Compare encrypted password from login form WITH encrypted password from db
5. If there is a match, login successful
6. If no match, login NOT successful
Note:
The password from db is
NEVER decrypted
Because bcrypt is a
one-way
encryption
algorithm

springb security.pptxdsdsgfdsgsdgsdgsdgdsgdsgds

  • 1.
    syllabus… • Secure SpringBoot REST APIs • Define users and roles • Protect URLs based on role • Store users, passwords and roles in DB (plain-text -> encrypted)
  • 2.
    Spring Security Model •Spring Security defines a framework for security • Implemented using Servlet filters in the background • Two methods of securing an app: declarative and programmatic
  • 3.
    Spring Security withServlet Filters • Servlet Filters are used to pre-process / post-process web requests • Servlet Filters can route web requests based on security logic • Spring provides a bulk of security functionality with servlet filters
  • 4.
    Spring Security Overview Spring Security Filters Web Browser myapp security configuration users passwords roles Protected Web Resource /mytopsecretstuff
  • 5.
    Spring Security inAction Spring Security Filters
  • 6.
    Spring Security Filters Check if userid and password are valid Spring Security in ActiDoones user have authorized role?
  • 7.
    Security Concepts • Authentication •Check user id and password with credentials stored in app / db • Authorization • Check to see if user has an authorized role
  • 8.
    Declarative Security • Defineapplication’s security constraints in configuration • All Java config: @Configuration • Provides separation of concerns between application code and security
  • 9.
    Programmatic Security • SpringSecurity provides an API for custom application coding • Provides greater customization for specific app requirements
  • 10.
    Enabling Spring Security 1.Edit pom.xml and add spring-boot-starter-security 2.This will automagically secure all endpoints for application <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency>
  • 11.
    Secured Endpoints • Nowwhen you access your application • Spring Security will prompt for login Check console logs for password Default user name: user
  • 12.
    Spring Security configuration • Youcan override default user name and generated password File: src/main/resources/application.properties spring.security.user.name=scott spring.security.user.password=test123
  • 13.
    Authentication and Authorization •In-memory • JDBC • LDAP • Custom / Pluggable • others … users passwords roles We will cover password storage in DB as plain-text AND encrypted
  • 14.
  • 15.
    Our Users User IDPassword Roles john test123 EMPLOYEE mary test123 EMPLOYEE, MANAGER susan test123 EMPLOYEE, MANAGER, ADMIN We can give ANY names for user roles
  • 16.
    Development Process 1. CreateSpring Security Configuration (@Configuration) 2. Add users, passwords and roles Step-By-Step
  • 17.
    Step 1: CreateSpring Security Configuration File: DemoSecurityConfig.java import org.springframework.context.annotation.Configuration; @Configuration public class DemoSecurityConfig { // add our security configurations here … }
  • 18.
    Spring Security PasswordStorage • In Spring Security, passwords are stored using a specific format {id}encodedPassword ID Description noop Plain text passwords bcrypt BCrypt password hashing … …
  • 19.
    Password Example {noop}test123 Let’s SpringSecurity know the passwords are stored as plain text (noop) The encoding algorithm id The password
  • 20.
    Step 2: Addusers, passwords and roles "ADMIN") UserDetails susan = User.builder() .username("susan") .password("{noop}test123") .roles("EMPLOYEE", "MANAGER", .build(); return new InMemoryUserDetailsManager(john, mary, susan); } } File: DemoSecurityConfig.java @Configuration public class DemoSecurityConfig { @Bean public InMemoryUserDetailsManager userDetailsManager() { UserDetails john = User.builder() .username("john") .password("{noop}test123") .roles("EMPLOYEE") .build(); UserDetails mary = User.builder() .username("mary") .password("{noop}test123") .roles("EMPLOYEE", "MANAGER") .build(); We will add DB support in later videos (plaintext and encrypted)
  • 21.
  • 22.
    Our Example HTTP MethodEndpoint CRUD Action Role GET /api/employees Read all EMPLOYEE GET /api/employees/{employeeId} Read single EMPLOYEE POST /api/employees Create MANAGER PUT /api/employees Update MANAGER DELETE /api/employees/{employeeId} Delete employee ADMIN
  • 23.
    Restricting Access to Roles •General Syntax requestMatchers(<< add path to match on >>) .hasRole(<< authorized role >>) Single role “ADMIN” Restrict access to a given path “/api/employees”
  • 24.
    Restricting Access to Roles requestMatchers(<<add HTTP METHOD to match on >>, << add path to match on >>) .hasRole(<< authorized roles >>) Specify HTTP method: GET, POST, PUT, DELETE … Single role Restrict access to a given path “/api/employees”
  • 25.
    Restricting Access to Roles requestMatchers(<<add HTTP METHOD to match on >>, << add path to match on >>) .hasAnyRole(<< list of authorized roles >>) Comma-delimited list Any role
  • 26.
    Authorize Requests forEMPLOYEE role requestMatchers(HttpMethod.GET, requestMatchers(HttpMethod.GET, "/api/employees").hasRole("EMPLOYEE") "/api/employees/**").hasRole("EMPLOYEE") The ** syntax: match on all sub-paths
  • 27.
    Authorize Requests forMANAGER role "/api/employees").hasRole("MANAGER") requestMatchers(HttpMethod.POST, requestMatchers(HttpMethod.PUT, "/api/employees").hasRole("MANAGER")
  • 28.
    Authorize Requests forADMIN role requestMatchers(HttpMethod.DELETE, "/api/employees/**").hasRole("ADMIN")
  • 29.
    Pull It Together @Bean publicSecurityFilterChain filterChain(HttpSecurity http) throws Exception { http.authorizeHttpRequests(configurer -> configurer .requestMatchers(HttpMethod.GET, .requestMatchers(HttpMethod.GET, .requestMatchers(HttpMethod.POST, .requestMatchers(HttpMethod.PUT, "/api/employees").hasRole("EMPLOYEE") "/api/employees/**").hasRole("EMPLOYEE") "/api/employees").hasRole("MANAGER") "/api/employees").hasRole("MANAGER") .requestMatchers(HttpMethod.DELETE, "/api/employees/**").hasRole("ADMIN")); // use HTTP Basic authentication http.httpBasic(Customizer.withDefaults()); return http.build(); } Use HTTP Basic Authentication
  • 30.
    Cross-Site Request Forgery(CSRF) • Spring Security can protect against CSRF attacks • Embed additional authentication data/token into all HTML forms • On subsequent requests, web app will verify token before processing • Primary use case is traditional web applications (HTML forms etc …)
  • 31.
    When to useCSRF Protection? • The Spring Security team recommends • Use CSRF protection for any normal browser web requests • Traditional web apps with HTML forms to add/modify data • If you are building a REST API for non-browser clients • you may want to disable CSRF protection • In general, not required for stateless REST APIs • That use POST, PUT, DELETE and/or PATCH
  • 32.
    Pull It Together @Bean publicSecurityFilterChain filterChain(HttpSecurity http) throws Exception { http.authorizeHttpRequests(configurer -> configurer .requestMatchers(HttpMethod.GET, .requestMatchers(HttpMethod.GET, .requestMatchers(HttpMethod.POST, .requestMatchers(HttpMethod.PUT, "/api/employees").hasRole("EMPLOYEE") "/api/employees/**").hasRole("EMPLOYEE") "/api/employees").hasRole("MANAGER") "/api/employees").hasRole("MANAGER") .requestMatchers(HttpMethod.DELETE, "/api/employees/**").hasRole("ADMIN")); // use HTTP Basic authentication http.httpBasic(Customizer.withDefaults()); // disable Cross Site Request Forgery (CSRF) http.csrf(csrf -> csrf.disable()); return http.build(); } In general, CSRF is not required for stateless REST APIs that use POST, PUT, DELETE and/or PATCH
  • 33.
    Database Access • Sofar, our user accounts were hard coded in Java source code • We want to add database access Advanced
  • 34.
    Recall Our UserRoles User ID Password Roles john test123 EMPLOYEE mary test123 EMPLOYEE, MANAGER susan test123 EMPLOYEE, MANAGER, ADMIN
  • 35.
    Database Support inSpring Security • Spring Security can read user account info from database • By default, you have to follow Spring Security’s predefined table schemas Spring Security JDBC Code Out-of-the-box
  • 36.
    Customize Database Access withSpring Security • Can also customize the table schemas • Useful if you have custom tables specific to your project / custom • You will be responsible for developing the code to access the data • JDBC, JPA/Hibernate etc …
  • 37.
    Database Support inSpring Security • Follow Spring Security’s predefined table schemas Spring Security JDBC Code Out-of-the-box
  • 38.
    Development Process 1. DevelopSQL Script to set up database tables 2. Add database support to Maven POM file 3.Create JDBC properties file 4. Update Spring Security Configuration to use JDBC Step-By-Step
  • 39.
    Default Spring Security DatabaseSchema “authorities” same as “roles”
  • 40.
    Step 1: DevelopSQL Script to setup database tables CREATE TABLE `users` ( `username` varchar(50) NOT NULL, `password` varchar(50) NOT NULL, `enabled` tinyint NOT NULL, PRIMARY KEY (`username`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
  • 41.
    Step 1: DevelopSQL Script to setup database tables Let’s Spring Security know the passwords are stored as plain text (noop) The encoding algorithm id The password INSERT INTO `users` VALUES ('john','{noop}test 123',1), ('mary','{noop}test 123',1), ('susan','{noop}tes t123',1);
  • 42.
    Step 1: DevelopSQL Script to setup database tables CREATE TABLE `authorities` ( `username` varchar(50) NOT NULL, `authority` varchar(50) NOT NULL, UNIQUE KEY `authorities_idx_1` (`username`,`authority`), CONSTRAINT `authorities_ibfk_1` FOREIGN KEY (`username`) REFERENCES `users` (`username`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
  • 43.
    Step 1: DevelopSQL Script to setup database tables “authorities” same as “roles” INSERT INTO `authorities` VALUES ('john','ROLE_EMPLOYEE'), ('mary','ROLE_EMPLOYEE'), ('mary','ROLE_MANAGER'), ('susan','ROLE_EMPLOYEE') , ('susan','ROLE_MANAGER'), ('susan','ROLE_ADMIN'); Internally Spring Security uses “ROLE_” prefix
  • 44.
    Step 2: AddDatabase Support to Maven POM file <!-- MySQL --> <dependency> <groupId>com.mysql</groupId> <artifactId>mysql-connector-j</artifactId> <scope>runtime</scope> </dependency> JDBC Driver
  • 45.
    Step 3: CreateJDBC Properties File File: application.properties # # JDBC connection properties # spring.datasource.url=jdbc:mysql://localhost:3306/employee_directory spring.datasource.username=springstudent spring.datasource.password=springstudent
  • 46.
    Step 4: UpdateSpring Security to use JDBC @Configuration public class DemoSecurityConfig { @Bean public UserDetailsManager userDetailsManager(DataSource dataSource) { return new JdbcUserDetailsManager(dataSource); } … } Inject data source Auto-configured by Spring Boot Tell Spring Security to use JDBC authentication with our data source No longer hard-coding users :-)
  • 47.
    luv2code LLC m Spring SecurityPassword Encryption
  • 48.
    Password Storage • Sofar, our user passwords are stored in plaintext … yikes! • Ok for getting started … but not for production / real-time project :-(
  • 49.
    Password Storage -Best Practice • The best practice is store passwords in an encrypted format Best Practice Encrypted version of password
  • 50.
    Spring Security TeamRecommendation luv2code LLC • Spring Security recommends using the popular bcrypt algorithm • bcrypt • Performs one-way encrypted hashing • Adds a random salt to the password for additional protection • Includes support to defeat brute force attacks
  • 51.
    How to Geta Bcrypt password luv2code LLC You have a plaintext password and you want to encrypt using bcrypt • Option 1: Use a website utility to perform the encryption • Option 2: Write Java code to perform the encryption
  • 52.
    Spring Security LoginProcess 1. Retrieve password from db for the user 2. Read the encoding algorithm id (bcrypt etc) 3. For case of bcrypt, encrypt plaintext password from login form (using salt from db password) 4. Compare encrypted password from login form WITH encrypted password from db 5. If there is a match, login successful 6. If no match, login NOT successful Note: The password from db is NEVER decrypted Because bcrypt is a one-way encryption algorithm