在前后端分离的springboot项目中,后端只提供接口不提供页面,而spring security默认是以后端提供登录页面进行登录的。本文将构造一个最简的spring security的配置,以支持restful风格的后端项目接口登录。
SecurityConfig配置
@Configuration
@EnableWebSecurity(debug = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
/**
* 用户认证方法,身份验证逻辑
*/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// 定义在内存中的账户信息
auth.inMemoryAuthentication()
.withUser("admin").password(passwordEncoder().encode("123456")).roles("ADMIN")
.and()
.withUser("user").password(passwordEncoder().encode("123456")).roles("USER");
}
/**
* 权限规则相关
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
// 路径权限定义
http.authorizeRequests()
.antMatchers("/auth/all").permitAll() // 开放权限测试
.antMatchers("/auth/login").permitAll() // 登录页面和登录接口开放权限
.antMatchers("/auth/admin").hasRole("ADMIN") // 需要ADMIN角色才能访问
.anyRequest().authenticated(); // 其他路径需要基本验证
// 登录处理
http.formLogin() // 表单登录
.loginPage("/auth/login") // 该路径为get请求,登录页面 (访问)
.loginProcessingUrl("/auth/login") // 该路径为post请求,登录接口 (调用)
.successHandler((request, response, authentication) -> { // 登录成功处理
response.setContentType("application/json;charset=utf-8");
response.setStatus(HttpStatus.OK.value());
response.getWriter().write(authentication.getName() + " 登录成功");
})
.failureHandler((request, response, exception) -> { // 登录失败处理
response.setContentType("application/json;charset=utf-8");
response.setStatus(HttpStatus.OK.value()); // 200
response.getWriter().write("登录失败");
});
// 未验证请求处理
http.httpBasic().authenticationEntryPoint((request, response, authException) -> {
response.setContentType("application/json;charset=utf-8");
response.setStatus(HttpStatus.UNAUTHORIZED.value()); // 401未授权
response.getWriter().write("请登录");
});
// 拒绝访问处理
http.exceptionHandling().accessDeniedHandler((request, response, accessDeniedException) -> {
response.setContentType("application/json;charset=utf-8");
response.setStatus(HttpStatus.FORBIDDEN.value()); // 403权限不足
response.getWriter().write("无权限");
});
http.csrf().disable(); // 禁用csrf防护
}
/**
* 密码加密方法
*/
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
这段配置类代码配置了测试用户信息,登录、鉴权等处理逻辑。使得前端在调用后端接口时能够得到正确的响应。
接口层定义
@RestController
@RequestMapping("/auth")
public class AuthController {
@GetMapping("/all")
public String test() {
return "auth all";
}
@GetMapping("/login")
public String login() {
return "<登录页面> —— 请登录";
}
@GetMapping("/ping")
public String pong() {
return "pong";
}
@GetMapping("/admin")
public String admin() {
return "管理员权限访问";
}
}
/auth/all 不经验证即可访问
/auth/ping 经过基本验证可访问
/auth/admin 管理员权限可访问
接口测试
/auth/all 无需验证 成功-
user登录测试-
-
登录成功,触发successhandle,并且返回头中有cookie信息
将cookie作为请求头,使用user账户进行测试-
-
/auth/ping 正常
/auth/admin 则由于权限不足被accessDeniedHandler处理
让我们用admin账户登录,并使用cookie重新测试-
-
使用admin账户成功访问!