欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Spring Security控制的简单应用

程序员文章站 2022-05-25 11:54:17
...

在编写Web应用时,经常需要做一些验证性的工作,如游客(未登陆用户)不拥有某些功能的执行权限。
要实现访问控制的方法多种多样,可以通过Aop、拦截器实现,也可以通过框架实现(如:Apache Shiro、Spring Security)。
在Qunar(去哪儿)培训中验证用户登陆使用到Spring Security对某些权限进行控制,因此总结一下各个小节点。

映射页面部分内容:

  • resources/templates/showDiff.html
  • 这是一个上传两个文件并且比较文件内容差异的简单页面,文件的内容规定为key=value的键值对,每对占一行
  • 该页面同时包含登陆和注销按钮
<!DOCTYPE html>
<html  xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4">
<head>
    <title>比较详情</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<form action="/upload" method="post" enctype="multipart/form-data">
    <input type="file" required="true" name="source"/>
    <input type="file" required="true" name="target"/>
    <input type="submit" value="上传文件"/>
</form>
<div style="text-align: center;margin:0 auto;width: 1000px; ">
    <table width="100%" border="1" cellspacing="1" cellpadding="0">
        <tr>
            <td>比较时间</td>
            <td>源文件内容</td>
            <td>目标文件内容</td>
            <td>差异</td>
        </tr>
        <tr th:each="model: ${resultList}">
            <td th:text="${#dates.format(model.compareTime,'yyyy-MM-dd HH:mm:ss')}"></td>
            <td th:text="${model.source}"></td>
            <td th:text="${model.target}"></td>
            <td th:text="${model.difference}"></td>
            <div sec:authorize="hasRole('UU')">
                <td> <a th:href=" @{/delectRecord(id=${model.id})}">删除</a></td>
            </div>
        </tr>
    </table>
    <td><a th:href="@{list(pageNumber = ${pageNumber},pageSize=${pageSize})}" th:if="${total}-${pageNumber}*${pageSize} gt 0">查看更多</a></td>
    <td><a th:href="@{list(pageNumber = ${preNumber},pageSize=${pageSize})}" th:if="${pageNumber} gt 1">上一页</a></td>
    <form th:action="@{/logout}" method="post">
        <input type="submit" value="注销"/>
    </form>
    <form th:action="@{/login}" method="post">
        <input type="submit" value="登录"/>
    </form>
</div>
</body>
</html>

其中包含一个“删除”超链接,该连接在加持Spring Security时只有登陆用户才能进行操作

  • 删除超链接
<div sec:authorize="hasRole('UU')">
    <td> <a th:href=" @{/delectRecord(id=${model.id})}">删除</a></td>
</div>
  • 登陆和注销
<form th:action="@{/logout}" method="post">
    <input type="submit" value="注销"/>
</form>
<form th:action="@{/login}" method="post">
    <input type="submit" value="登录"/>
</form>

添加依赖
在pom.xml中添加如下配置,引入对Spring Security的依赖。

<dependencies>
    ...
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
    ...
</dependencies>

Spring Security配置

  • 创建Spring Security的配置类LoginSecurity
  • 通过@EnableWebSecurity注解开启Spring
  • Security的功能 继承WebSecurityConfigurerAdapter,并重写它的方法来设置一些web安全的细节
  • configure(HttpSecurity httpSecurity)方法通过authorizeRequests()定义哪些URL需要被保护、哪些不需要被保护。例如以上代码指定了/和/list还有/upload不需要任何认证就可以访问,其他的路径都必须通过身份验证
  • 通过formLogin()定义当需要用户登录时候,转到的登录页面
@Configuration
@EnableWebSecurity
public class LoginSecurity extends WebSecurityConfigurerAdapter {
    @Resource
    private UserDao userDao;
    @Override
    protected void configure(AuthenticationManagerBuilder authenticationManager) throws Exception {
        for (Map.Entry<String, String> entry : userDao.getUserInfo().entrySet()) {
            authenticationManager.inMemoryAuthentication().withUser(entry.getKey()).password(entry.getValue())
                    .roles("UU");
        }
    }

    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception {
        httpSecurity.csrf().disable();
        httpSecurity.authorizeRequests().antMatchers("/", "/list", "/upload").permitAll().anyRequest().authenticated()
                .and().formLogin().loginPage("/login").permitAll().and().logout().permitAll();
    }

}

Controller层(部分代码如下):
- "/login"映射到login.html

@Controller
public class CompareController {

    private static final Logger LOGGER = LoggerFactory.getLogger(CompareController.class);

    @RequestMapping("/delectRecord")
    public ModelAndView delectRecord(@RequestParam("id") Integer id) {
        compareService.deleteRecordByID(id);
        return listTest(2, 0);
    }

    @RequestMapping("/login")
    public String login() {
        return "login";
    }
}
  • login.html(resources/templates/login.html)
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    ....
</head>
<body>
    ....
        <div class="container">
            <h1>Welcome</h1>
            <form class="form" th:action="@{/login}" method="post">
                <input type="text" placeholder="用户名" name="username" />
                <input type="password" placeholder="密码" name="password" />
                <button type="submit" id="login-button">登陆</button>
            </form>
        </div>
    ....
</body>
</html>

这样,点击登陆按钮就会跳到登陆页面进行登陆,若登陆成功便是“UU”角色就能看到记录的删除按钮并进行相应的操作啦。

参考链接:Spring Boot中使用Spring Security进行安全控制