网站后台需要一个登录验证的部分,我在shiro和Spring Security中选择了后者。
首先在pom.xml中导入Spring Security的stater:
<!-- Spring Security -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
然后编写配置类:
package com.dzy.config;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// 只拦截LidarSet开头的URL
http.authorizeRequests().antMatchers("/").permitAll()
.antMatchers("/LidarLabSet/**").hasRole("admin");
// 使用默认的登录页面
http.formLogin();
// 使用spring security的登出
http.logout().logoutSuccessUrl("/LidarLab/home");
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
.withUser("yonghuming")
.password(new BCryptPasswordEncoder().encode("mima"))
.roles("admin");
}
}
到这个时候,Spring Security就已经生效了!
并且Spring Security会自动生成/login和/logout两个请求和对应页面,当访问被拦截的地址时,会自动跳转到/login,至于/logout,则可以手动的在导航栏中设计一个超链接使用/logout。
<ul class="layui-nav layui-layout-right">
<li class="layui-nav-item"><a th:href="@{/logout}">log out</a></li>
</ul>
这样,最基本的功能就做出来了!
但是,有一个问题,通过Ajax请求的资源全部403。
原因是SpringSecurity默认是禁止接收POST请求的,而GET是默认可以的,官网给出两个解决方案:
- 发送请求时带上CSRF的token
- 把SpringSecurity的CSRF功能关掉(不推荐)。
我们当然是选择第一种了,具体的操作方法是(使用thymeleaf+layui的方法):
在每一个页面的head标签里添加两个meta标签:
<meta name="_csrf" th:content="${_csrf.token}">
<meta name="_csrf_header" th:content="${_csrf.headerName}">
然后在每个页面的js区域加上一下代码:
layui.use('jquery',function() {
var $= layui.jquery;
var token = $("meta[name='_csrf']").attr("content");
var header = $("meta[name='_csrf_header']").attr("content");
$(document).ajaxSend(function (e, xhr, options) {
xhr.setRequestHeader(header, token);
});
});
然后Ajax也都可以正常使用了!