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

08 Spring Boot 3 Spring MVC Security

This document provides an overview of securing a Spring MVC web application with Spring Security. It discusses developing login pages, defining users and roles, protecting URLs based on roles, and storing user data in a database. The document outlines setting up a basic Spring Security configuration and exploring different login methods like HTTP basic authentication and custom login forms.

Uploaded by

def46917
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)
111 views

08 Spring Boot 3 Spring MVC Security

This document provides an overview of securing a Spring MVC web application with Spring Security. It discusses developing login pages, defining users and roles, protecting URLs based on roles, and storing user data in a database. The document outlines setting up a basic Spring Security configuration and exploring different login methods like HTTP basic authentication and custom login forms.

Uploaded by

def46917
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/ 158

Spring MVC

Security Overview

© luv2code LLC
You will learn how to …
• Secure Spring MVC Web App

• Develop login pages (default and custom

• De ne users and roles with simple authenticatio


fi
n

• Protect URLs based on rol

• Hide/show content based on role

• Store users, passwords and roles in DB (plain-text -> encrypted)

www.luv2code.com © luv2code LLC


Practical Results
• Cover the most common Spring Security tasks that you will need on daily projects

• Not an A to Z reference … for that you can see Spring Security Reference Manual

http://www.luv2code.com/spring-security-reference-manual

www.luv2code.com © luv2code LLC


Spring Security Model
• Spring Security de nes a framework for security

fi
• Implemented using Servlet lters in the background

fi
• Two methods of securing an app: declarative and programmatic

www.luv2code.com © luv2code LLC


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 lters

fi
www.luv2code.com © luv2code LLC
Spring Security Overview
/mytopsecretstuff

Protected
Web
Resource
Web Spring
Browser Security
Filters
my app users
security passwords
configuration roles

www.luv2code.com © luv2code LLC


Spring Security in Action

Spring
Security
Filters

www.luv2code.com © luv2code LLC


Spring Security in Action
Does user have
authorized role?

Spring
Security
Filters
Check if user id and
password are valid

www.luv2code.com © luv2code LLC


Security Concepts
• Authenticatio

• Check user id and password with credentials stored in app / db

• Authorizatio
n

• Check to see if user has an authorized role

www.luv2code.com © luv2code LLC


Declarative Security
• De ne application’s security constraints in con guratio
fi
fi
n

• All Java con g: @Con guration

fi
fi
• Provides separation of concerns between application code and security

www.luv2code.com © luv2code LLC


Programmatic Security
• Spring Security provides an API for custom application coding

• Provides greater customization for speci c app requirements

fi
www.luv2code.com © luv2code LLC
Enabling Spring Security
1. Edit pom.xml and add spring-boot-starter-security

<dependency

>

<groupId>org.springframework.boot</groupId

>

<artifactId>spring-boot-starter-security</artifactId

>

</dependency>

2.This will automagically secure all endpoints for application

www.luv2code.com © luv2code LLC


Secured Endpoints
• Now when you access your applicatio

• Spring Security will prompt for login

Check console log

for password

Default user name: user

www.luv2code.com © luv2code LLC


Different Login Methods
• HTTP Basic Authentication

• Default login for

• Spring Security provides a default login form

• Custom login for


m

• your own look-and-feel, HTML + CSS

www.luv2code.com © luv2code LLC


HTTP Basic Authentication

Built-in Dialog
from browser

bleh!

www.luv2code.com © luv2code LLC


Spring Security - Default Login Form

Good for quick start

www.luv2code.com © luv2code LLC


Your Own Custom Login Form

Your own custom


look-and-feel
HTML + CSS

www.luv2code.com © luv2code LLC


Spring Security Demo

© luv2code LLC
Recap of our Game Plan
• Secure Spring MVC Web App

• Develop login pages (default and custom

• De ne users and roles with simple authenticatio


fi
n

• Protect URLs based on rol

• Hide/show content based on role

• Store users, passwords and roles in DB (plain-text -> encrypted)

www.luv2code.com © luv2code LLC


Our Example /leaders

Leadership
Retreat
Page

/ role: MANAGER

Home Page

role: EMPLOYEE /systems

Admin
Holiday
Cruise

role: ADMIN
www.luv2code.com © luv2code LLC
Spring MVC Security
Project Setup

© luv2code LLC
Development Process
Step-
By-S
tep
1. Create project at Spring Initializr websit

1. Add Maven dependencies for Spring MVC Web App, Security, Thymeleaf

2. Develop our Spring controller

3. Develop our Thymeleaf view page

www.luv2code.com © luv2code LLC


Step 1: Add Maven dependencies for Spring MVC Web App
File: pom.xml

...
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId> Spring MVC web support
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId> Thymeleaf view support
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId> Spring Security support
</dependency>

<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity6</artifactId> Thymeleaf Security support
</dependency>
...

www.luv2code.com © luv2code LLC


Step 2: Develop our Spring Controller
File: DemoController.java

@Controlle

public class DemoController

@GetMapping("/"

public String showHome()

return "home"
;

View name
}

src/main/resources/templates/ home .html

www.luv2code.com © luv2code LLC


Step 3: Develop our Thymeleaf view page
File: src/main/resources/templates/home.html

<html>

<body>

Welcome to the luv2code company home page

</body>

</html>

www.luv2code.com © luv2code LLC


Get Fresh Web Session

• Option 1:

• Start new web browser

• Option 2:

• In web browser and open new Private / Incognito window

www.luv2code.com
Configuring Basic Security

© luv2code LLC
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

www.luv2code.com © luv2code LLC


Development Process
Step-
By-S
tep
1. Create Spring Security Con guration (@Con guration)

fi
fi
2. Add users, passwords and roles

www.luv2code.com © luv2code LLC


Step 1: Create Spring Security Configuration

File: DemoSecurityCon g.java

fi
import org.springframework.context.annotation.Configuration

@Configuratio
n

public class DemoSecurityConfig

// add our security configurations here

www.luv2code.com © luv2code LLC


Spring Security Password Storage
• In Spring Security, passwords are stored using a speci c format

fi
{id}encodedPasswor

ID Description
noop Plain text passwords

bcrypt BCrypt password hashing

… …

www.luv2code.com © luv2code LLC


Password Example
The encoding
The passwor
algorithm i

{noop}test123

Let’s Spring Security


know the passwords are
stored as plain text (noop)

www.luv2code.com © luv2code LLC


Step 2: Add users, passwords and roles
File: DemoSecurityCon g.java

fi
@Configuratio

public class DemoSecurityConfig

@Bea
n

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()
;

UserDetails susan = User.builder(


We will add DB support in
later videos
)

.username("susan"
)

.password("{noop}test123"
)

.roles("EMPLOYEE", "MANAGER", "ADMIN"

.build() (plaintext and encrypted)


;

return new InMemoryUserDetailsManager(john, mary, susan)

www.luv2code.com © luv2code LLC


Spring Security - Custom Login Form

© luv2code LLC
Spring Security - Default Login Form

Good for quick start

www.luv2code.com © luv2code LLC


Your Own Custom Login Form

Your own custom


look-and-feel
HTML + CSS

www.luv2code.com © luv2code LLC


Spring Security Overview
/mytopsecretstuff

Protected
Web
Resource
Web Spring
Browser Security
Filters
my app users
security passwords
configuration roles

www.luv2code.com © luv2code LLC


Spring Security in Action

Spring
Security
Filters

Our custom
login form

www.luv2code.com © luv2code LLC


Development Process Step-
By-S
tep

1. Modify Spring Security Con guration to reference custom login form

fi
2. Develop a Controller to show the custom login form

3. Create custom login form


✤ HTML (CSS optional)

www.luv2code.com © luv2code LLC


Step 1: Modify Spring Security Configuration
File: DemoSecurityCon g.java

fi
@Bea
n

public SecurityFilterChain filterChain(HttpSecurity http) throws Exception

http.authorizeHttpRequests(configurer -

>

configure
Configure security of web paths

.anyRequest().authenticated(

in application, login, logout etc


)

.formLogin(form -

>

for
m

.loginPage("/showMyLoginPage"

.loginProcessingUrl("/authenticateTheUser"

.permitAll(

)
;

return http.build()
;

www.luv2code.com © luv2code LLC


Step 1: Modify Spring Security Configuration
File: DemoSecurityCon g.java

fi
@Bea
n

public SecurityFilterChain filterChain(HttpSecurity http) throws Exception

http.authorizeHttpRequests(configurer -
Any request to the app

>

configure

.anyRequest().authenticated(
must be authenticated

(ie logged in)


)

.formLogin(form -

>

for
m

.loginPage("/showMyLoginPage"

.loginProcessingUrl("/authenticateTheUser"

.permitAll(

)
;

return http.build()
;

www.luv2code.com © luv2code LLC


Step 1: Modify Spring Security Configuration
File: DemoSecurityCon g.java

fi
@Bea
n

public SecurityFilterChain filterChain(HttpSecurity http) throws Exception

http.authorizeHttpRequests(configurer -

>

configure

.anyRequest().authenticated(
We are customizing the form

.formLogin(form - login process


>

for
m

.loginPage("/showMyLoginPage"

.loginProcessingUrl("/authenticateTheUser"

.permitAll(

)
;

return http.build()
;

www.luv2code.com © luv2code LLC


Step 1: Modify Spring Security Configuration
File: DemoSecurityCon g.java

fi
@Bea
n

public SecurityFilterChain filterChain(HttpSecurity http) throws Exception

http.authorizeHttpRequests(configurer - Show our custom form at the

>

configure request mapping

.anyRequest().authenticated(

“/showMyLoginPage”
)

.formLogin(form -

>

for
m

.loginPage("/showMyLoginPage"

.loginProcessingUrl("/authenticateTheUser"

.permitAll(

)
;

return http.build()
;

www.luv2code.com © luv2code LLC


Step 1: Modify Spring Security Configuration
File: DemoSecurityCon g.java

fi
@Bea
n

public SecurityFilterChain filterChain(HttpSecurity http) throws Exception

http.authorizeHttpRequests(configurer -
Login form should POST data to this

>

configure
URL for processing

.anyRequest().authenticated(

.formLogin(form - (check user id and password)


>

for
m

.loginPage("/showMyLoginPage"

.loginProcessingUrl("/authenticateTheUser"

.permitAll(

)
;

return http.build()
;

www.luv2code.com © luv2code LLC


Step 1: Modify Spring Security Configuration
File: DemoSecurityCon g.java

fi
@Bea
You can give ANY values
n

public SecurityFilterChain filterChain(HttpSecurity http) throws Exception

http.authorizeHttpRequests(configurer -
for this configuration.

>

configure

.anyRequest().authenticated( Just stay consistent in your app

.formLogin(form -

>

for
m

.loginPage("/showMyLoginPage"

.loginProcessingUrl("/authenticateTheUser"

.permitAll(

)
;

return http.build()
;

www.luv2code.com © luv2code LLC


Step 1: Modify Spring Security Configuration
File: DemoSecurityCon g.java

fi
@Bea
n

public SecurityFilterChain filterChain(HttpSecurity http) throws Exception

http.authorizeHttpRequests(configurer -

>

configure

.anyRequest().authenticated(

.formLogin(form -

>

for
m

.loginPage("/showMyLoginPage"

.loginProcessingUrl("/authenticateTheUser"

.permitAll(

)
;

return http.build()
Allow everyone to see login page.
;

}
No need to be logged in.

www.luv2code.com © luv2code LLC


Step 1: Modify Spring Security Configuration
File: DemoSecurityCon g.java

fi
@Bea
n

public SecurityFilterChain filterChain(HttpSecurity http) throws Exception

http.authorizeHttpRequests(configurer -

>

configure

.anyRequest().authenticated(

.formLogin(form -

>

for
m

.loginPage("/showMyLoginPage"

.loginProcessingUrl("/authenticateTheUser"

.permitAll(

)
;

return http.build()
Allow everyone to see login page.
;

}
No need to be logged in.

www.luv2code.com © luv2code LLC


Step 1: Modify Spring Security Configuration
File: DemoSecurityCon g.java
TO DO

fi
@Bea We need to create a controller
n

public SecurityFilterChain filterChain(HttpSecurity http) throws


for this request mapping
Exception

http.authorizeHttpRequests(configurer -

>

configure “/showMyLoginPage”

.anyRequest().authenticated(

.formLogin(form -

>

for
m

.loginPage("/showMyLoginPage"

.loginProcessingUrl("/authenticateTheUser"

.permitAll(

)
;

return http.build()
;

www.luv2code.com © luv2code LLC


Step 1: Modify Spring Security Configuration
File: DemoSecurityCon g.java

fi
@Bea
n

public SecurityFilterChain filterChain(HttpSecurity http) throws Exception

http.authorizeHttpRequests(configurer -

>

configure

.anyRequest().authenticated(

.formLogin(form -

>

for
m

.loginPage("/showMyLoginPage"

.loginProcessingUrl("/authenticateTheUser"

.permitAll(

)
;

return http.build()
No Controller Request Mapping
;

}
required for this.
We get this for free :-)

www.luv2code.com © luv2code LLC


Step 2: Develop a Controller to show the custom login form
File: LoginController.java

@Controller
public class LoginController {

@GetMapping("/showMyLoginPage")
public String showMyLoginPage() {

return "plain-login";

}
}

www.luv2code.com © luv2code LLC


Step 2: Develop a Controller to show the custom login form
File: LoginController.java

@Controller
public class LoginController {

@GetMapping("/showMyLoginPage")
public String showMyLoginPage() {

return "plain-login";

}
}

www.luv2code.com © luv2code LLC


Step 2: Develop a Controller to show the custom login form
File: LoginController.java

@Controller
public class LoginController {

@GetMapping("/showMyLoginPage")
public String showMyLoginPage() {

return "plain-login";
TO DO
} View name
}
We need to create this file

src/main/resources/templates/plain-login.html

www.luv2code.com © luv2code LLC


Step 3: Create custom login form
• Send data to login processing URL: /authenticateTheUser

/authenticateTheUser

Spring
Security
Filters
You can give ANY values
for this configuration.

Just stay consistent in your app

www.luv2code.com © luv2code LLC


Step 3: Create custom login form
• Send data to login processing URL: /authenticateTheUser

• Login processing URL will be handled by Spring Security Filters

• You get it for free … no coding required

This is

Spring Security magic …


LOL

www.luv2code.com © luv2code LLC


Step 3: Create custom login form
• Send data to login processing URL: /authenticateTheUser

• Must POST the data

<form action="#" th:action="@{/authenticateTheUser}"


method="POST">

</form>

www.luv2code.com © luv2code LLC


Step 3: Create custom login form
• Spring Security de nes default names for login form eld

fi
fi
s

• User name eld: username Spring Security Filters

fi
will read the form data and
• Password eld: password
fi
authenticate the user

User name: <input type="text" name="username" />

Password: <input type="password" name="password" />

www.luv2code.com © luv2code LLC


Step 3: Create custom login form Pull I
Toge
t All
ther
File: src/main/resources/templates/plain-login.html


<form action="#" th:action="@{/authenticateTheUser}"
method="POST">

<p>
User name: <input type="text" name="username" />
</p>

<p>
Password: <input type="password" name="password" />
</p>

<input type="submit" value="Login" />

</form>

www.luv2code.com © luv2code LLC


Step 3: Create custom login form Pull I
Toge
t All
ther
File: src/main/resources/templates/plain-login.html


<form action="#" th:action="@{/authenticateTheUser}"
method="POST">

<p>
User name: <input type="text" name="username" />
</p>

<p>
Password: <input type="password" name="password" />
</p>

<input type="submit" value="Login" />

</form>

www.luv2code.com © luv2code LLC


Step 3: Create custom login form Pull I
Toge
t All
ther
File: src/main/resources/templates/plain-login.html


<form action="#" th:action="@{/authenticateTheUser}"
method="POST">

<p>
User name: <input type="text" name="username" />
</p>

<p>
Password: <input type="password" name="password" />
</p>

<input type="submit" value="Login" />

</form>

www.luv2code.com © luv2code LLC


Spring Security in Action

Spring
Security
Filters

www.luv2code.com © luv2code LLC


More Info on Context Path What is this??

The @ symbol

<form action="#" th:action="@{/authenticateTheUser}"


method="POST">

www.luv2code.com © luv2code LLC


More Info on Context Path Context Path

is same thing as
Context Root

www.luv2code.com © luv2code LLC


More Info on Context Path
Gives us access to

context path dynamically

<form action="#" th:action="@{/authenticateTheUser}"


method="POST">

www.luv2code.com © luv2code LLC


Why use Context Path? Best
Pract
i ce
• Allows us to dynamically reference context path of application

• Helps to keep links relative to application context path

• If you change context path of app, then links will still work

• Much better than hard-coding context path …

www.luv2code.com © luv2code LLC


Spring Security - Show Login Error

m
No error message for failed login - What???

No error message???

www.luv2code.com
We need an error message … ASAP!!!

We’ll add this


support

www.luv2code.com
Failed Login

• When login fails, by default Spring Security will …

• Send user back to your login page

• Append an error parameter: ?error

www.luv2code.com
Failed Login

www.luv2code.com
Failed Login

Failed Login

Send back to
Login Form

www.luv2code.com
Failed Login
http://localhost:8080/myapp/showMyLoginPage?error

Failed Login

Append param to URL:


error
Send back to
Login Form

www.luv2code.com
Failed Login
http://localhost:8080/myapp/showMyLoginPage?error

Failed Login

Append param to URL:


error
Send back to
Login Form

www.luv2code.com
Development Process
Step-
By-S
tep

1. Modify custom login for

1.Check the error paramete

2.If error parameter exists, show an error message

www.luv2code.com
Step 1: Modify form - check for error
File: src/main/resources/templates/plain-login.html
If error param
… then show message
<form …>

<div th:if="${param.error}">

<i>Sorry! You entered invalid username/password.</i>

</div>

User name: <input type="text" name="username" />


Password: <input type="password" name="password" />

</form>

www.luv2code.com
Step 1: Modify form - check for error
File: src/main/resources/templates/plain-login.html
If error param
… then show message
<form …>

<div th:if="${param.error}">

<i>Sorry! You entered invalid username/password.</i>

</div>

User name: <input type="text" name="username" />


Password: <input type="password" name="password" />

</form>
http://localhost:8080/myapp/showMyLoginPage?error

www.luv2code.com
Spring Security - Bootstrap Login Page

© luv2code LLC
Let’s Make our Login Form Beautiful
Before After

Bootstrap

www.luv2code.com © luv2code LLC


Bootstrap
• Bootstrap is a web framework that includes CSS styles and JavaScript

• Focused on front-end UI

• For our project, you do not need any experience with Bootstrap :-)

www.luv2code.com © luv2code LLC


Our Game Plan
• My friend, Alan, has helped us out

• He created an HTML login form using Bootstrap

• We’ll modify the form to use Spring Security for our project

www.luv2code.com © luv2code LLC


Fancy Login Form

www.luv2code.com © luv2code LLC


Development Process
Step-
By-S
1. Modify form to point to our login processing URL tep

2. Verify form elds for username and password


fi
3. Change our controller to use our new Bootstrap login form

www.luv2code.com © luv2code LLC


Bootstrap Tutorials and Docs
• There are tons of free tutorials online: “bootstrap tutorial”

www.w3schools.com/bootstrap

• Bootstrap Of cial Documentation


fi
www.getbootstrap.com/docs

www.luv2code.com © luv2code LLC


Spring Security - Logout

© luv2code LLC
Logging Out

Clear user’s
session

www.luv2code.com © luv2code LLC


Development Process
Step-
By-S
tep
1. Add logout support to Spring Security Con guration

fi
2. Add logout button to home page

3. Update login form to display “logged out” message

www.luv2code.com © luv2code LLC


Step 1: Add Logout support to Spring Security Configuration
File: DemoSecurityCon g.java

fi
@Bea
n

public SecurityFilterChain filterChain(HttpSecurity http) throws Exception

http.authorizeHttpRequests(configurer -

>

configure

.anyRequest().authenticated(

.formLogin(form -

>

for
m

.loginPage("/showMyLoginPage"

.loginProcessingUrl("/authenticateTheUser"

.permitAll(

.logout(logout -> logout.permitAll( Add logout support

)
for default URL
;

return http.build() /logout


;

www.luv2code.com © luv2code LLC


Step 2: Add logout button
• Send data to default logout URL: /logout

• Logout URL will be handled by Spring Security Filters

• You get it for free … no coding required

This is

Spring Security magic …


LOL

www.luv2code.com © luv2code LLC


Step 2: Add logout button
• Send data to default logout URL: /logout

• By default, must use POST method

<form action="#" th:action="@{/logout}" method="POST">

<input type="submit" value="Logout" />

</form>
GET method is disabled
by default

www.luv2code.com © luv2code LLC


Logout process
• When a logout is processed, by default Spring Security will …

• Invalidate user’s HTTP session and remove session cookies, etc

• Send user back to your login page

• Append a logout parameter: ?logout

www.luv2code.com © luv2code LLC


Step 3: Update login form to display “logged out” message

1. Update login for

1.Check the logout paramete

2.If logout parameter exists, show “logged out” message

www.luv2code.com © luv2code LLC


Modify Login form - check for "logout"
File: src/main/resources/templates/plain-login.html


<form … th:action="…" method="…">

<div th:if="${param.logout}"> If logout param then


show message
<i>You have been logged out.</i>

</div>

User name: <input type="text" name="username" />


Password: <input type="password" name="password" />

</form>

www.luv2code.com © luv2code LLC


Modify Login form - check for "logout"
File: src/main/resources/templates/plain-login.html


<form … th:action="…" method="…">

<div th:if="${param.logout}"> If logout param then


show message
<i>You have been logged out.</i>

</div>

User name: <input type="text" name="username" />


Password: <input type="password" name="password" />

</form> http://localhost:8080/showMyLoginPage?logout

www.luv2code.com © luv2code LLC


Display User ID and Roles

© luv2code LLC
Display User ID and Roles

User ID Role

www.luv2code.com © luv2code LLC


Spring Security
• Spring Security provides support for accessing user id and roles

www.luv2code.com © luv2code LLC


Development Process
Step-
By-S
tep
1. Display User ID

2. Display User Roles

www.luv2code.com © luv2code LLC


Step 1: Display User ID

File: home.html

User: <span sec:authentication="principal.username"></span>

User ID

www.luv2code.com © luv2code LLC


Step 2: Display User Roles
File: home.html

Role(s): <span sec:authentication="principal.authorities"></span>

User
Roles

www.luv2code.com © luv2code LLC


Restrict Access Based on Roles

© luv2code LLC
Our Example /leaders

Leadership
Retreat
Page

/ role: MANAGER

Home Page

role: EMPLOYEE /systems

Admin
Holiday
Cruise

role: ADMIN
www.luv2code.com © luv2code LLC
Development Process
Step-
By-S
tep

1. Create supporting controller code and view pages


2. Restrict Access based on Roles

www.luv2code.com © luv2code LLC


Step 1: Create Supporting Controller code and View Pages

Cover these steps


in the video

www.luv2code.com © luv2code LLC


Step 2: Restricting Access to Roles
• Update your Spring Security Java con guration le (.java

fi
fi
)

• General Syntax
Single role

requestMatchers(<< add path to match on >>).hasRole(<< authorized role >>)

Restrict access to “ADMIN”


a given path
“/systems/**”

www.luv2code.com © luv2code LLC


Step 3: Restricting Access to Roles

Any role in the list, comma-delimited list

requestMatchers(<< add path to match on >>).hasAnyRole(<< list of authorized roles >>)

“ADMIN”, “DEVELOPER”, “VIP”, “PLATINUM”

www.luv2code.com © luv2code LLC


Restrict Path to EMPLOYEE

requestMatchers("/").hasRole("EMPLOYEE")

Match on root path: /

www.luv2code.com © luv2code LLC


Restrict Path /leaders to MANAGER

requestMatchers("/leaders/**").hasRole("MANAGER")

Match on path: /leaders


And all sub-directories (**)

www.luv2code.com © luv2code LLC


Restrict Path /systems to ADMIN

requestMatchers("/systems/**").hasRole("ADMIN")

Match on path: /systems


And all sub-directories (**)

www.luv2code.com © luv2code LLC


Pull It Together
@Bea
n

public SecurityFilterChain filterChain(HttpSecurity http) throws Exception

http.authorizeHttpRequests(configurer -

>

configure

.requestMatchers("/").hasRole("EMPLOYEE"

.requestMatchers("/leaders/**").hasRole("MANAGER"

.requestMatchers("/systems/**").hasRole("ADMIN"

.anyRequest().authenticated(

www.luv2code.com © luv2code LLC


Custom Access Denied Page

© luv2code LLC
Default Access Denied Page

www.luv2code.com © luv2code LLC


Custom Access Denied Page

You can customize this page

HTML + CSS

www.luv2code.com © luv2code LLC


Development Process
Step-
By-S
tep
1. Con gure custom page for access denied
fi
2. Create supporting controller code and view page

www.luv2code.com © luv2code LLC


Step 1: Configure custom page access denied
@Bea
n

public SecurityFilterChain filterChain(HttpSecurity http) throws Exception

http.authorizeHttpRequests(configurer -

>

configure

.requestMatchers(“/").hasRole("EMPLOYEE"

.exceptionHandling(configurer -

>

configure

.accessDeniedPage("/access-denied"

)
;

}
Our request mapping path

www.luv2code.com © luv2code LLC


Step 2: Create Supporting Controller code and View Page

Cover these steps


in the video

www.luv2code.com © luv2code LLC


Display Content Based on Roles

© luv2code LLC
Why Show These Links?

Since John is an
employee,

he shouldn’t be able
to see this content / links

www.luv2code.com © luv2code LLC


Display Content Based on Roles
Logged in
as Mary

Mary can see


MANAGER content

www.luv2code.com © luv2code LLC


Spring Security Only show this section for users
with MANAGER role


<div sec:authorize="hasRole('MANAGER')">

<p>
<a th:href="@{/leaders}">
Leadership Meeting
</a>
(Only for Manager peeps)
</p>

</div>

www.luv2code.com © luv2code LLC


Display Content Based on Roles
Logged in
as Susan

Susan can see


ADMIN content

www.luv2code.com © luv2code LLC


Spring Security Only show this section for users
with ADMIN role


<div sec:authorize="hasRole('ADMIN')">

<p>
<a th:href="@{/systems}">
IT Systems Meeting
</a>
(Only for Admin peeps)
</p>

</div>

www.luv2code.com © luv2code LLC


Spring Securit

User Accounts Stored in Database

m
Database Access
• So far, our user accounts were hard coded in Java source code

• We want to add database access Advan


ced

www.luv2code.com
Recall Our User Roles

User ID Password Roles


john test123 EMPLOYEE

mary test123 EMPLOYEE, MANAGER

susan test123 EMPLOYEE, MANAGER, ADMIN

www.luv2code.com
Database Support in Spring Security Out-o
f-the-
box
• Spring Security can read user account info from database

• By default, you have to follow Spring Security’s prede ned table schemas

fi
Spring JDBC
Security Code

www.luv2code.com
Customize Database Access with Spring Security

• Can also customize the table schemas

• Useful if you have custom tables speci c to your project / custom

fi
• You will be responsible for developing the code to access the dat

• JDBC, JPA/Hibernate etc …

www.luv2code.com
Database Support in Spring Security Out-o
f-the-
box
• Follow Spring Security’s prede ned table schemas

fi
Spring JDBC
Security Code

www.luv2code.com
Development Process
Step-
By-S
tep
1. Develop SQL Script to set up database tables

2. Add database support to Maven POM le

fi
3.Create JDBC properties le
fi
4. Update Spring Security Con guration to use JDBC
fi
www.luv2code.com
Default Spring Security Database Schema

“authorities” same as “roles”

www.luv2code.com
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;

www.luv2code.com
Step 1: Develop SQL Script to setup database tables
The encoding algorithm i

The passwor

INSERT INTO `users`


VALUES
('john','{noop}test123',1),
('mary','{noop}test123',1),
('susan','{noop}test123',1);

Let’s Spring Security know the


passwords are stored as plain text
(noop)

www.luv2code.com
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;

www.luv2code.com
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_” pre x
fi
www.luv2code.com
Step 2: Add Database Support to Maven POM file

<!-- MySQL -->


<dependency JDBC Driver
>

<groupId>com.mysql</groupId

>

<artifactId>mysql-connector-j</artifactId

>

<scope>runtime</scope

>

</dependency
>

www.luv2code.com
Step 3: Create JDBC Properties File
File: application.properties
#
# JDBC connection properties
#
spring.datasource.url=jdbc:mysql://localhost:3306/employee_director

spring.datasource.username=springstuden

spring.datasource.password=springstuden

www.luv2code.com
Step 4: Update Spring Security to use JDBC
Inject data source

Auto-con gured by Spring Boot

fi
@Configuratio
n

public class DemoSecurityConfig

@Bea
n

public UserDetailsManager userDetailsManager(DataSource dataSource)

return new JdbcUserDetailsManager(dataSource)


No longer

hard-coding users :-)


} Tell Spring Security to use

JDBC authentication

with our data source

www.luv2code.com
Spring Securit

Password Encryption

© luv2code LLC
Password Storage
• So far, our user passwords are stored in plaintext … yikes!

• Ok for getting started … but not for production / real-time project :-(

www.luv2code.com © luv2code LLC


Password Storage - Best Practice Best P
ractic
e
• The best practice is store passwords in an encrypted format

Encrypted version of password

www.luv2code.com © luv2code LLC


Spring Security Team Recommendation

• Spring Security recommends using the popular bcrypt algorithm

• bcryp
t

• Performs one-way encrypted hashin

• Adds a random salt to the password for additional protectio

• Includes support to defeat brute force attacks

www.luv2code.com © luv2code LLC


Bcrypt Additional Information
• Why you should use bcrypt to hash password

www.luv2code.com/why-bcrypt

• Detailed bcrypt algorithm analysi

www.luv2code.com/bcrypt-wiki-page

• Password hashing - Best Practices

www.luv2code.com/password-hashing-best-practices

www.luv2code.com © luv2code LLC


How to Get a Bcrypt password

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

www.luv2code.com © luv2code LLC


How to Get a Bcrypt password - Website
• Visit: www.luv2code.com/generate-bcrypt-password

• Enter your plaintext password

• The website will generate a bcrypt password for you

www.luv2code.com © luv2code LLC


DEMO
www.luv2code.com © luv2code LLC
Development Process
Step-
By-S
tep

1. Run SQL Script that contains encrypted password

Modify DDL for password eld, length should be 68

fi
THAT’S IT … no need to change Java source code :-)

www.luv2code.com © luv2code LLC


Spring Security Password Storage
• In Spring Security, passwords are stored using a speci c format

fi
Password column must be at least 68 chars wide
{bcrypt}encodedPasswor

{bcrypt} - 8 char

encodedPassword - 60 chars

www.luv2code.com © luv2code LLC


Modify DDL for Password Field

CREATE TABLE `users` (


Password column must be at least 68 chars wide
`username` varchar(50) NOT NULL,
`password` char(68) NOT NULL, {bcrypt} - 8 char

`enabled` tinyint NOT NULL, encodedPassword - 60 chars

PRIMARY KEY (`username`)

) ENGINE=InnoDB DEFAULT CHARSET=latin1;

www.luv2code.com © luv2code LLC


Step 1: Develop SQL Script to setup database tables
The encoding
algorithm i
The encrypted password: fun123
d

INSERT INTO `users`


VALUES
(‘john','{bcrypt}$2a$10$qeS0HEh7urweMojsnwNAR.vcXJeXR1UcMRZ2WcGQl9YeuspUdgF.q',1),

Let’s Spring Security know the


passwords are stored as
encrypted passwords: bcrypt

www.luv2code.com © luv2code LLC


Step 1: Develop SQL Script to setup database tables
The encoding
algorithm i
The encrypted password: fun123
d

INSERT INTO `users`


VALUES
(‘john','{bcrypt}$2a$10$qeS0HEh7urweMojsnwNAR.vcXJeXR1UcMRZ2WcGQl9YeuspUdgF.q',1),

('mary','{bcrypt}$2a$04$eFytJDGtjbThXa80FyOOBuFdK2IwjyWefYkMpiBEFlpBwDH.5PM0K',1),

('susan','{bcrypt}$2a$04$eFytJDGtjbThXa80FyOOBuFdK2IwjyWefYkMpiBEFlpBwDH.5PM0K',1);

www.luv2code.com © luv2code LLC


Spring Security Login Process

User enters
plaintext password

Spring
Web
Security
Browser
Filters

www.luv2code.com © luv2code LLC


Spring Security Login Process

Note

The password from db is


NEVER decrypted

Because bcrypt is a

1. Retrieve password from db for the user one-way

encryption algorith
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

www.luv2code.com © luv2code LLC


Spring Securit

Custom Tables

© luv2code LLC
Default Spring Security Database Schema

www.luv2code.com © luv2code LLC


Custom Tables
• What if we have our own custom tables

• Our own custom column names?

This is all custo


m

Nothing matches with default Spring Security table schema

www.luv2code.com © luv2code LLC


For Security Schema Customization
• Tell Spring how to query your custom tables

• Provide query to nd user by user name


fi
• Provide query to nd authorities / roles by user name
fi
www.luv2code.com © luv2code LLC
Development Process
Step-
By-S
tep
1. Create our custom tables with SQL

2. Update Spring Security Con guratio

fi
n

• Provide query to nd user by user nam


fi
e

• Provide query to nd authorities / roles by user name


fi
www.luv2code.com © luv2code LLC
Step 1: Create our custom tables with SQL

This is all custo

Nothing matches with default Spring Security table schema

www.luv2code.com © luv2code LLC


Step 2: Update Spring Security Configuration

@Configuratio
n

public class DemoSecurityConfig

@Bea
n

public UserDetailsManager userDetailsManager(DataSource dataSource)

JdbcUserDetailsManager theUserDetailsManager = new JdbcUserDetailsManager(dataSource)

theUserDetailsManage
r

.setUsersByUsernameQuery("select user_id, pw, active from members where user_id=?")

theUserDetailsManage
r

.setAuthoritiesByUsernameQuery("select user_id, role from roles where user_id=?")

return theUserDetailsManager
;

www.luv2code.com © luv2code LLC


Step 2: Update Spring Security Configuration

@Configuratio
n

public class DemoSecurityConfig

@Bea
n

public UserDetailsManager userDetailsManager(DataSource dataSource)

JdbcUserDetailsManager theUserDetailsManager = new JdbcUserDetailsManager(dataSource)

theUserDetailsManage How to nd users


r

fi
.setUsersByUsernameQuery("select user_id, pw, active from members where user_id=?")

theUserDetailsManage
r

.setAuthoritiesByUsernameQuery("select user_id, role from roles where user_id=?")


How to nd roles

fi
return theUserDetailsManager
;


Question mark “?

}
Parameter value will be the

user name from login

www.luv2code.com © luv2code LLC

You might also like