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.