For those who have finished working on the Spring Quickstart Guide, those who have started learning Spring Boot, and those who want to review it.
We will share what we have learned by actually working on the official guide Securing a Web Application.
Check the completed form. There is a top page, click here,
Go to the login page. Enter the username and password for the test user and click the Sign in button
You will be taken to a page that can only be viewed by authenticated people. You cannot access this screen if you are not logged in.
The development environment and the review so far are as follows.
Development environment
OS: macOS Mojave version 10.14.6
Text editor: Visual Studio Code (hereinafter VSCode)
Java: 11.0.2
QuickstartGuide Building a RESTful Web Service Consuming a RESTful Web Service Accessing Data with JPA Handling Form Submission Securing a Web Application
First, access spring initializr.
Spring Web
and Thymeleaf
.
2.Artifact, Name changed to securing-web
.Java to 11
.Then click the GENERATE
button to download the Zip file.
Extract the downloaded Zip file and you're ready to go.
Open the previous folder with VS Code. We recommend installing the Java Extension Pack for extensions. It is said that you should install it.
Create a home.html file in src / main / resources / templates /
.
Add the code referring to the formula. It will be the top page.
home.html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="https://www.thymeleaf.org"
xmlns:sec="https://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
<head>
<title>Spring Security Example</title>
</head>
<body>
<h1>Welcome!</h1>
<p>Click <a th:href="@{/hello}">here</a> to see a greeting.</p>
</body>
</html>
The html tag part is for writing th: 〇〇
and sec: 〇〇
(the description method using thymeleaf and Spring Security tags becomes possible).
Now let's dig deeper into the description of thymeleaf in the added code.
thymeleaf is a template engine that can be handled by springboot. Described as th: 〇〇. [Thymeleaf tutorial] written in Japanese (https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf_ja.html#thymeleaf%E3%81%AE%E7%B4%B9%E4%BB% There is also 8B)!
th:href
This tag is set in the href attribute of the a tag. The description method is th: href =" @ {} "
.
Specify the path in {}
. This time it is / hello
, so if you click the tag, it will transition to http: // localhost: 8080 / hello
.
Create a hello.html file in src / main / resources / templates /
.
Add the code referring to the formula.
hello.html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="https://www.thymeleaf.org"
xmlns:sec="https://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
<head>
<title>Hello World!</title>
</head>
<body>
<h1 th:inline="text">Hello [[${#httpServletRequest.remoteUser}]]!</h1>
<form th:action="@{/logout}" method="post">
<input type="submit" value="Sign Out"/>
</form>
</body>
</html>
th: inline
is for expanding the value of a variable in the text of the tag. Enclose the variable you want to display in [[...]]
.
This time, it is $ {# httpServletRequest.remoteUser}
, so the name of the authenticated user is displayed.
When the Sign Out
button is pressed, you will be redirected to / login? Logout
.
Create an MvcConfig.java file in src / main / java / com / example / securingweb /
.
Add the code referring to the formula.
MvcConfig.java
package com.example.securingweb;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class MvcConfig implements WebMvcConfigurer {
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/home").setViewName("home");
registry.addViewController("/").setViewName("home");
registry.addViewController("/hello").setViewName("hello");
registry.addViewController("/login").setViewName("login");
}
}
The ** @ Configuration
** annotation is added to the class so that various Spring settings can be performed in Java code. (Setting class)
I have created an MvcConfig class that implements the WebMvcConfigurer interface and overrides the addViewControllers method.
registry.addViewController("/home").setViewName("home");
Instead of having another Controller and using the @GetMapping
annotation to return the View name
By the above description
When the URL is http: // localhost: 8080 / home
, the template ** home.html ** will be referenced.
It seems that the URL and template are mapped.
Login.html will be implemented later.
Add the following to pom.xml to use Spring Security.
Spring Security is a framework for adding security features to web applications. Provides comprehensive support for authentication, authorization, and protection against common abuse.
pom.xml
<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>
Create a WebSecurityConfig.java file in src / main / java / com / example / securingweb /
.
Add the code referring to the formula.
WebSecurityConfig.java
package com.example.securingweb;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/", "/home").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
String password = passwordEncoder().encode("password");
auth.inMemoryAuthentication()
.passwordEncoder(passwordEncoder())
.withUser("user").password(password).roles("USER");
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
We will dig deeper into the added code.
@EnableWebSecurity
and WebSecurityConfigurerAdapter
classesWebSecurityConfig.java
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
//abridgement
}
Spring Security is enabled by adding the @EnableWebSecurity
annotation.
And it inherits an abstract class called WebSecurityConfigurerAdapter
. Override the ** configure method ** in this class
We will implement whether or not to restrict page access.
WebSecurityConfig.java
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/", "/home").permitAll() //URLs that do not require access restrictions
.anyRequest().authenticated() //Other URLs require authentication. You cannot access it unless you are authenticated
.and()
.formLogin()
.loginPage("/login") //No access restrictions on the login screen
.permitAll() //No authentication required
.and()
.logout()
.permitAll(); //No authentication required
}
Overriding ** configure method **. HttpSecurity is received as an argument, and it is a method for describing the settings for the part related to http request. Set whether authentication is required when logging in, logging out, or accessing other pages.
The implementation of this part has been said to be deprecated if you follow the official guide. So it has a slightly different implementation.
WebSecurityConfig.java
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//Encode password
String password = passwordEncoder().encode("password");
//Settings for in-memory authentication
auth.inMemoryAuthentication()
.passwordEncoder(passwordEncoder())
.withUser("user").password(password).roles("USER");
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
** PasswordEncoder passwordEncoder ()
** defines a method for hashing passwords.
Then, the password of the string is hashed with String password = passwordEncoder (). Encode ("password");
.
AuthenticationManagerBuilder is a class that enables in-memory authentication.
python
//Settings for in-memory authentication
auth.inMemoryAuthentication()
.passwordEncoder(passwordEncoder())
.withUser("user").password(password).roles("USER");
}
We implement it here and set the user to authenticate.
Create a login.html file in src / main / resources / templates /
.
Add the code referring to the formula. It will be the login page.
login.html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="https://www.thymeleaf.org"
xmlns:sec="https://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
<head>
<title>Spring Security Example </title>
</head>
<body>
<div th:if="${param.error}">
Invalid username and password.
</div>
<div th:if="${param.logout}">
You have been logged out.
</div>
<form th:action="@{/login}" method="post">
<div><label> User Name : <input type="text" name="username"/> </label></div>
<div><label> Password: <input type="password" name="password"/> </label></div>
<div><input type="submit" value="Sign In"/></div>
</form>
</body>
</html>
There is a field to enter the User Name and Password.
th: if =" $ {param.error}
is the area displayed when user authentication fails.
th: if =" $ {param.logout}
is the area that will be displayed when you sign out (displayed after the Sign Out button is pressed in hello.html).
Now that the application is ready to run, let's check.
Enter the following command in the terminal and press Enter.
Terminal
$ ./mvnw spring-boot:run
The top page is displayed.
Click here to go to the login page.
Enter an appropriate User Name and Password and press the Sign In button.
The login page is redisplayed and the error message is also displayed.
Next, enter ʻuser in Uesr Name and
password` in Password and press the Sign In button.
I was able to transition to a page that can only be viewed by authenticated people.
When you press the Sign Out button,
You'll be redirected to the login page and you'll see a message.
Thank you for your hard work. done!
** Deprecated alternative to User.withDefaultPasswordEncoder () ** ** [Spring Security has started] # 2 User Authentication ** ** "Hello World!" With Spring Security **
Recommended Posts