Springboot Integration Spring Security 03 - Access Control

Springboot Integration Spring Security 03 - Access Control

stay Springboot Integration Spring Security 02 - Use custom landing pages We have learned to customize our own landing page.
Let's continue to learn about Spring Security's permission control.

1. Configure our static resources and update the landing page

Usually our web pages need to refer to static css, images and other resources. So here we simulate normal development scenarios.
Create a test.css under the static/css directory. The contents are as follows:

.error {
    color: red;
}
.username {
    color: gray;
}

We introduced these static resources into our custom login.html login page.

<!DOCTYPE HTML>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" >
<link rel="stylesheet" type="text/css" th:href="@{/static/css/test.css}"/>
<body>
<h1>This is My Login Page</h1>
<form th:action="@{/login}" method="post">
    <p th:if="${error != null}">
        <span>
            <font class="error">Invalid username and password.</font>
        </span>
    </p>
    <p th:if="${logout != null}">
        <span>You are logout.</span>
    </p>
    <p>
        <label for="username">Username</label>
        <input class="username" type="text" id="username" name="username"/>
    </p>
    <p>
        <label for="password">Password</label>
        <input type="password" id="password" name="password"/>
    </p>
    <input type="hidden"
           th:name="${_csrf.parameterName}"
           th:value="${_csrf.token}"/>
    <button type="submit" class="btn">Log in</button>
</form>
</body>
</html>

2. Create several interfaces

package com.demo.spring.security.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * @author flw
 */
@Controller
public class HelloController {

    @GetMapping("hello")
    public String hello() {
        return "hello";
    }
    @GetMapping("login")
    public String login(@RequestParam(required = false) String error,
                        @RequestParam(required = false) String logout,
                        Model model) {
        if (error != null) {
            model.addAttribute("error", "error");
        }
        if (logout != null) {
            model.addAttribute("logout", "logout");
        }
        return "login";
    }
    @GetMapping("/common/hello")
    @ResponseBody
    public String common() {
        return "common";
    }
    @GetMapping("/user/hello")
    @ResponseBody
    public String user() {
        return "user";
    }
    @GetMapping("/admin/hello")
    @ResponseBody
    public String admin() {
        return "admin";
    }
}

Here we create three additional interfaces. / common/hello, / user/hello, / admin/hello
Used to wait for us to set permission access usage.

3. Configure Web Security Config

@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter  {

    @Bean
    @Override
    public UserDetailsService userDetailsService() {
        InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
        manager.createUser(User.withDefaultPasswordEncoder().username("user")
                .password("user").roles("USER").build());
        manager.createUser(User.withDefaultPasswordEncoder().username("admin")
                .password("admin").roles("ADMIN").build());
        manager.createUser(User.withDefaultPasswordEncoder().username("dba")
                .password("dba").roles("DBA","USER").build());
        return manager;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                .antMatchers("/static/**", "/common/**").permitAll()
                .antMatchers("/admin/**").hasRole("ADMIN")
                .antMatchers("/user/**").access("hasRole('USER') and hasRole('DBA')")
                .anyRequest().authenticated()
                .and()
                .formLogin()
                .loginPage("/login")
                .permitAll();
    }
}

UserDetails Service (): Here we create three users. User only has USER permissions, admin only has ADMIN permissions, and DBA has two specific permissions: USER and DBA.
configure(HttpSecurity http): In this case, we configure requests for / static /** and / common /** paths that do not require any privileges or even login. / ADMIN /** requests require ADMIN privileges, and both USER and DBA privileges exist to access the requests of / user /**.

4. Start the project.

4.1 First we access / common/hello, an interface that does not require permissions.
http://localhost:10022/security/common/hello

Common strings can be returned directly after browser input. Requests describing the / common /** path do not require any permissions, and can be accessed without even logging in.

4.2 Then we access the / admin/hello interface
http://localhost:10022/security/admin/hello

You can see that we jumped to the landing page, and through F12 you can see that our test.css was released, indicating that static resources can be accessed.

Then we enter admin/admin's account password.

You can normally access http://localhost:10022/security/admin/hello and return the admin string.

Then we visit the / user/hello interface and try again.

http://localhost:10022/security/admin/hello

You can see the error returned on the browser:

Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.

Thu Sep 12 21:06:56 CST 2019
There was an unexpected error (type=Forbidden, status=403).
Forbidden

The request was dropped by forbidden, proving that admin has no access to / user/hello.

4.3 Continue to access / user/hello

First, let's go back to login.

http://localhost:10022/security/login

Enter user/user
At this time, the page may be wrong, don't worry, because we did not set the default landing success jump page.
And this time we entered the landing page directly, so there was no successful jump page after landing, resulting in 404.

When the login is complete, we request the / user/hello interface in the browser

http://localhost:10022/security/user/hello

The result is still 403, because we set up requests for / user /** that require both DBA and USER privileges. So user users still do not meet the requirements.

Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.

Thu Sep 12 21:12:30 CST 2019
There was an unexpected error (type=Forbidden, status=403).
Forbidden

Now let's go back to the login page and login with dba/dba account password.
Then continue visiting http://localhost:10022/security/user/hello

You can see. This time the user string is returned correctly.

Keywords: Spring SpringBoot Thymeleaf

Added by bacil on Thu, 12 Sep 2019 16:23:28 +0300