Thymeleaf框架与Spring-Security框架集成

Thymeleaf与Spring Security框架的集成

当已经切换到Thymeleaf框架后,登录和错误页仍然使用JSP?这篇文章中我们将看到如何配置Spring应用程序中使用Thymeleaf的登录和错误页。

所有代码均可以从GitHub中下载

先决条件

首先会认为你已经熟悉了Thymeleaf和Spring Security框架,当然,也要有一个应用在使用这两个框架。如果你不了解Spring Security框架,可以查看Spring Security文档

登录

Spring security可以指定任何一个URL作为一个登录页,所以我们只需要设置登录页面和登录错误页的Url在Spring-Security配置文件的form-login节点的属性中(一般命名为applicationContext-security.xml)

<http auto-config="true">
    <form-login login-page="/login.html" authentication-failure-url="/login-error.html" />
    <logout />
    ...
</http>

现在需要为这些页面设置一个控制器:

@Controller
public class MainController {
    ...
    // 登录页
    @RequestMapping("/login.html")
    public String login() {
        return "login.html";
    }
    // 登录错误页
    @RequestMapping("/login-error.html")
    public String loginError(Model model) {
        model.addAttribute("loginError", true);
        return "login.html";
    }
}

注意:我们使用的相同的模板页:login.html,当如果有错误的时候,通过一个boolean属性来区分.

下面是错误模板:

<!DOCTYPE html>
<html>
    <head>
        <title>登录</title>
    </head>
    <body>
        <h1>登录页面</h1>
        <p th:if="${loginError}">您的用户名或密码错误</p>
        <form th:action="@{/j_spring_security_check}" method="post">
            <label for="j_username">用户名</label>:
            <input type="text" id="j_username" name="j_username" /> <br />
            <label for="j_password">密码</label>:
            <input type="password" id="j_password" name="j_password" /> <br />
            <input type="submit" value="登录" />
        </form>
    </body>
</html>

错误页

我们还可以配置一个Thymeleaf的错误页,在这种情况下,Spring Security不参与,我们只需修改web.xml(或在Spring4.x中修改配置类)添加error-page节点:

<error-page>
  <exception-type>java.lang.Throwable</exception-type>
  <location>/error.html</location>
</error-page>
<error-page>
  <error-code>500</error-code>
  <location>/error.html</location>
</error-page>

然后在Spring控制器中设置错误页:

@Controller
public class HomeController {
  ...
  // 错误页
  @RequestMapping("/error.html")
  public String error(HttpServletRequest request, Model model) {
    model.addAttribute("errorCode", request.getAttribute("javax.servlet.error.status_code"));
    Throwable throwable = (Throwable) request.getAttribute("javax.servlet.error.exception");
    String errorMessage = null;
    if (throwable != null) {
      errorMessage = throwable.getMessage();
    }
    model.addAttribute("errorMessage", errorMessage);
    return "error.html";
  }
}

请注意,我们将错误代码和错误信息都以及输入到模型中,用于静态中默认显示页面中的信息:

error.html模板如下:

<!DOCTYPE html>
<html>
  <head>
    <title>错误页</title>
  </head>
  <body>
    <h1 th:text="${errorCode}">500</h1>
    <p th:text="${errorMessage}">java.lang.NullPointerException</p>
  </body>
</html>

Spring security方言

Spring Security4的集成模块可以使用Thymeleaf方言相当于Spring security框架的默认标签。

在下面这个例子中使用这个方言,并打印出用户登录的凭证,并根据不同的角色显示不同的内容。

当属性表达式的执行结果为true的时候,属性sec:authorize渲染出内容:

<div sec:authorize="hasRole('ROLE_ADMIN')">
  角色为admin的时候展示
</div>
<div sec:authorize="hasRole('ROLE_USER')">
  角色为user的时候展示
</div>

属性 sec:authentication 可以用于打印用户名和角色:

登录: <span sec:authentication="name">张三</span>
角色: <span sec:authentication="principal.authorities">[ROLE_USER, ROLE_ADMIN]</span