Lab18 security view all
We'd like to "lock down" the "view all orders" screen so it can only be seen by an admin.
A. Configure Dependencies¶
Add the following dependencies to the pom.xml
file to pull in the necessary security dependencies.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity4</artifactId>
<version>3.0.2.RELEASE</version>
</dependency>
B. Configure the Security Adapter¶
Configure the security so that the /coffee-orders
page can only be accessed by an ADMIN.
Add the following class, named SecurityConfig
to your project:
package com.welltestedlearning.cvm;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.User;
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
// @formatter:off
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/coffee-orders").hasRole("ADMIN")
.and()
.formLogin()
.loginPage("/login")
.failureUrl("/login-error");
}
// @formatter:on
// @formatter:off
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("admin")
.password("admin")
.roles("ADMIN");
}
// @formatter:on
}
C. Add Login Page¶
Create a new template, called login.html
:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Admin Login Page</title>
</head>
<body>
<h2>Admin Login Page</h2>
<form th:action="@{/login}" method="post">
<p th:if="${loginError}">Invalid username and/or password.</p>
<div>
<label for="username">Username:</label>
<input type="text" id="username" name="username" autofocus="autofocus"/>
</div>
<div>
<label for="password">Password:</label>
<input type="password" id="password" name="password"/>
</div>
<input type="submit" value="Log in"/>
</form>
</body>
</html>
D. Create Login Controller¶
Create a controller class, called WebLoginController
that will serve up and process the login template:
@Controller
public class WebLoginController {
@GetMapping("/login")
public String login() {
return "login";
}
@GetMapping("/login-error")
public String loginError(Model model) {
model.addAttribute("loginError", true);
return "login";
}
}
Now try going to the view all orders page (localhost:8080/coffee-orders
), and you'll see that you need to log in first.
Also try logging in with incorrect credentials to see what happens.
E. Add Security to Template¶
The Thymeleaf security tags start with sec
and you can restrict parts of a page like this:
<div sec:authorize="isAuthenticated()">
This content is only shown to authenticated users.
</div>
To use the sec
prefix, you'll need to add the namespace like this, at the top of the HTML file:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/extras/spring-security"
>
You can also display information about the logged-in user like this:
<p>Logged user: <span sec:authentication="name">Bob</span></p>
<p>Roles: <span sec:authentication="principal.authorities">user</span></p>
Add these to the page and then view it to see the name and its roles.