Spring Boot + Spring Security + Thymeleaf 举例 - Go语言中文社区

Spring Boot + Spring Security + Thymeleaf 举例


本文以Spring Boot Thymeleaf为例,用Spring Security 保护 /admin 和 /user 页面

本例涉及的技术:

1. Spring Boot 1.5.6.REALEASE

2. Spring 4.3.8.REALEASE

3. Spring Security 4.2.2

4. Thymeleaf 2.2.5.REALEASE

5. Tomcat embed 8.5.14

6. Maven 3

7. Java 8

1. 项目目录结构


2. 项目依赖 pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>org.thinkingingis</groupId>
  <artifactId>spring-boot-security</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>spring-boot-security</name>
  <url>http://maven.apache.org</url>

  <parent>
  	<groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.6.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
  </parent>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <java.version>1.8</java.version>
  </properties>
  
  <dependencies>
  	    <!-- Spring Security -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.thymeleaf.extras</groupId>
            <artifactId>thymeleaf-extras-springsecurity4</artifactId>
        </dependency>
         
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>bootstrap</artifactId>
            <version>3.3.7</version>
        </dependency>
  </dependencies>
  <build>
  	<plugins>
  		   	<!-- Package as an executable jar/war -->
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
  	</plugins>
  </build>

</project>

3. Spring Security

3.1 继承自WebSecurityConfigurerAdapter 同时在configure方法中定义了安全角色

对于admin(管理员)角色来说:

a. 可以访问/admin.html页面

b. 不能访问/user.html页面,并重定向到403页面

对于user(用户)角色来说:

a.可以访问/user.html页面

b.不能访问/admin.html页面,并重定向到403页面

SpringSecurityConfig.java

@Configuration
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
	
	@Autowired
	private AccessDeniedHandler accessDeniedHandler;
	
	protected void configure(HttpSecurity http) throws Exception{
		http.csrf().disable()
				.authorizeRequests()
					.antMatchers("/", "/home", "/about").permitAll()
					.antMatchers("/admin/**").hasAnyRole("ADMIN")
					.antMatchers("/user/**").hasAnyRole("USER")
					.anyRequest().authenticated()
				.and()
				.formLogin()
					.loginPage("/login")
					.permitAll()
					.and()
				.logout()
					.permitAll()
					.and()
				.exceptionHandling().accessDeniedHandler(accessDeniedHandler);
	}
	
	//create two users admin and user
	@Autowired
	public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception{
		auth.inMemoryAuthentication()
				.withUser("user").password("password").roles("USER")
				.and()
				.withUser("admin").password("password").roles("ADMIN");
	}
	
}
3.2 定义403无权限访问的处理,重定向到/403页面

MyAccessDeniedHandler.java

@Component
public class MyAccessDeniedHandler implements AccessDeniedHandler {
	
	private static Logger logger = LoggerFactory.getLogger(MyAccessDeniedHandler.class);
	
	@Override
	public void handle( HttpServletRequest httpServletRequest, 
					    HttpServletResponse httpServletResponse, 
					    AccessDeniedException e)
			throws IOException, ServletException {
		
		Authentication auth = SecurityContextHolder.getContext().getAuthentication();
		
		if(auth != null) {
			logger.info("User '" + auth.getName() + "' attempted to access the protected URL: " + httpServletRequest.getRequestURI());
		}
		
		httpServletResponse.sendRedirect(httpServletRequest.getContextPath() + "/403");
	}

}

4. Spring Boot

4.1 DefaultController.java 

定义http请求和视图名

@Controller
public class DefaultController {
    
	@GetMapping("/")
    public String index() {
        return "/home";
    }

    @GetMapping("/home")
    public String home() {
        return "/home";
    }

    @GetMapping("/admin")
    public String admin() {
        return "/admin";
    }

    @GetMapping("/user")
    public String user() {
        return "/user";
    }

    @GetMapping("/about")
    public String about() {
        return "/about";
    }

    @GetMapping("/login")
    public String login() {
        return "/login";
    }

    @GetMapping("/403")
    public String error403() {
        return "/error/403";
    }
}

4.2 Spring Boot的启动程序

SpringBootWebApplication.java

@SpringBootApplication
public class SpringBootWebApplication {
	public static void main(String[] args) throws Exception {
		SpringApplication.run(SpringBootWebApplication.class, args);
	}

}

5.Thymeleaf及静态资源

对于 thymeleaf 文件,均放到 src/main/resources/templates/目录下

header.html

<html xmlns:th="http://www.thymeleaf.org">
<head>
    <div th:fragment="header-css">
        <link rel="stylesheet" type="text/css" href="webjars/bootstrap/3.3.7/css/bootstrap.min.css" />
        <link rel="stylesheet" th:href="@{/main.css}"/>
    </div>
</head>
<body>
<div th:fragment="header">
    <!-- this is header -->
    <nav class="navbar navbar-inverse">
        <div class="container">
            <div class="navbar-header">
                <a class="navbar-brand" th:href="@{/}">ThinkingInGIS</a>
            </div>
            <div id="navbar" class="collapse navbar-collapse">
                <ul class="nav navbar-nav">
                    <li class="active"><a th:href="@{/}">Home</a></li>
                </ul>
            </div>
        </div>
    </nav>
</div>
footer.html

<html xmlns="http://www.w3.org/1999/xhtml"
	  xmlns:th="http://www.thymeleaf.org"
      xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4">
<head>
</head>
<body>
<div th:fragment="footer">
    <div class="container">
        <footer>
        <!-- this is footer -->
        © 2017 ThinkingInGIS
            <span sec:authorize="isAuthenticated()">
                | Logged user: <span sec:authentication="name"></span> |
                Roles: <span sec:authentication="principal.authorities"></span> |
                <a th:href="@{/logout}">登出</a>
            </span>
        </footer>
    </div>
</div>
</body>
</html>
home.html
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Spring Boot Thymeleaf + Spring Security</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
    <link rel="stylesheet" type="text/css" href="webjars/bootstrap/3.3.7/css/bootstrap.min.css"/>
    <link rel="stylesheet" type="text/css" th:href="@{/main.css}"/>
   	<script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.js"></script>
</head>
<body>
<div th:replace="fragments/header :: header"></div>
<div class="container">
    <div class="starter-template">
        <h1>Spring Boot + Thymeleaf + Spring Security 示例</h1>
        <h2>1. 打开 <a th:href="@{/admin}">管理员页面 (受 Spring Security 保护, 需要管理员权限)</a></h2>
        <h2>2. 打开 <a th:href="@{/user}">用户页面 (受 Spring Security 保护, 需要用户权限)</a></h2>
        <h2>3. 打开 <a th:href="@{/about}">游客页面</a></h2>
    </div>
</div>
<div th:replace="fragments/footer :: footer"></div>
</body>
</html>

admin.html

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <link rel="stylesheet" type="text/css" href="webjars/bootstrap/3.3.7/css/bootstrap.min.css"/>
    <script type="text/javascript" src="webjars/jquery/2.2.4/jquery.min.js"></script>
</head>
<body>

<div class="container">
    <div class="starter-template">
        <h1>GORGEOUS! 管理员页面 (受 Spring Security 保护, 需要管理员权限)</h1>
        <h1 th:inline="text">Hello [[${#httpServletRequest.remoteUser}]]!</h1>
        <form th:action="@{/logout}" method="post">
            <input type="submit" class="btn btn-danger" value="登出"/>
        </form>
    </div>
</div>
<div class="container">
    <footer>
        <p>
            © <a >ThinkingInGIS</a> 2017
        </p>
    </footer>
</div>
</body>
</html>
user.html

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <link rel="stylesheet" type="text/css" href="webjars/bootstrap/3.3.7/css/bootstrap.min.css"/>
    <script type="text/javascript" src="webjars/jquery/2.2.4/jquery.min.js"></script>
</head>
<body>

<div class="container">
    <div class="starter-template">
        <h1>普通用户页面 (受 Spring Security 保护, 需要用户权限)</h1>
        <h1 th:inline="text">Hello [[${#httpServletRequest.remoteUser}]]!</h1>
        <form th:action="@{/logout}" method="post">
            <input type="submit" class="btn btn-danger" value="登出"/>
        </form>
    </div>
</div>
<div class="container">
    <footer>
        <p>
            © <a >ThinkingInGIS</a> 2017
        </p>
    </footer>
</div>
</body>
</html>
about.html
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <link rel="stylesheet" type="text/css" href="webjars/bootstrap/3.3.7/css/bootstrap.min.css"/>
    <script type="text/javascript" src="webjars/jquery/2.2.4/jquery.min.js"></script>
</head>
<body>

<div class="container">
    <div class="starter-template">
        <h1>游客页面 无需登录</h1>
    </div>
</div>
<div class="container">
    <footer>
        <p>
            © <a >ThinkingInGIS</a> 2017
        </p>
    </footer>
</div>
</body>
</html>

login.html

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
    <link rel="stylesheet" type="text/css" href="webjars/bootstrap/3.3.7/css/bootstrap.min.css"/>
    <script type="text/javascript" src="webjars/jquery/2.2.4/jquery.min.js"></script>
</head>
<body>
<div th:replace="fragments/header :: header"></div>
<div class="container">
    <div class="row" style="margin-top:20px">
        <div class="col-xs-12 col-sm-8 col-md-6 col-sm-offset-2 col-md-offset-3">
            <form th:action="@{/login}" method="post">
                <fieldset>
                    <h1>登录</h1>
                    <div th:if="${param.error}">
                        <div class="alert alert-danger">
                            Invalid username and password.
                        </div>
                    </div>
                    <div th:if="${param.logout}">
                        <div class="alert alert-info">
                            You have been logged out.
                        </div>
                    </div>

                    <div class="form-group">
                        <input type="text" name="username" id="username" class="form-control input-lg"
                               placeholder="用户名" required="true" autofocus="true"/>
                    </div>
                    <div class="form-group">
                        <input type="password" name="password" id="password" class="form-control input-lg"
                               placeholder="密码" required="true"/>
                    </div>

                    <div class="row">
                        <div class="col-xs-6 col-sm-6 col-md-6">
                            <input type="submit" class="btn btn-lg btn-primary btn-block" value="登录"/>
                        </div>
                        <div class="col-xs-6 col-sm-6 col-md-6">
                        </div>
                    </div>
                </fieldset>
            </form>
        </div>
    </div>

</div>

<div th:replace="fragments/footer :: footer"></div>

</body>
</html>
403.html

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
    <title>403</title>
    <link rel="stylesheet" type="text/css" href="webjars/bootstrap/3.3.7/css/bootstrap.min.css"/>
    <script type="text/javascript" src="webjars/jquery/2.2.4/jquery.min.js"></script>
</head>
<body>
<div th:replace="fragments/header :: header"></div>
<div class="container">
    <div class="starter-template">
        <h1>403 - 没有访问权限</h1>
        <div th:inline="text">Hello '[[${#httpServletRequest.remoteUser}]]',
                你没有权限访问此页面.</div>
    </div>
</div>
<!-- /.container -->
<div th:replace="fragments/footer :: footer"></div>

</body>
</html>
6.启动程序

6.1 /admin 下面的需要用admin用户登录才能访问

6.2 启动程序,访问 http://localhost:8080/

6.3 访问http://localhost:8080/admin 会被重定向到 http://localhost:8080/login


6.4 当输入无效的用户名和密码后...


6.5 用户名输入admin  密码输入 password 登录,页面会进入到 http://localhost:8080/admin


6.6 输入http://localhost:8080/user 会被重定向到 http://localhost:8080/403 最下面显示了登录的角色及用户名


6.7 点击 登出 会重定向到http://localhost:8080/login?logout


最后,自己试试 用 'user' 访问admin页面可看会有上面结果吧。

源码地址:https://github.com/ThinkingInGIS/spring-boot-security.git

至此,一个简单的spring boot + thymeleaf + spring security 程序 就搭建好了。
(如遇到问题,请留言给作者,以便共同探讨gis知识。thinkingingis@qq.com)
更多干货 欢迎关注微信公众号: ThinkingInGIS


如果觉得本文对你有帮助,是可以赞赏作者的哦


版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/gisboygogogo/article/details/78758815
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2020-03-08 14:18:31
  • 阅读 ( 1539 )
  • 分类:

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢