Spring Security 基础教程 -- HttpSecurity 权限和登录表单配置
HttpSecurity 权限配置
主要是通过 HttpSecurity 配置访问控制权限,它仍是继承自 WebSecurityConfigurerAdapter ,重写其中的 configure(HttpSecurity http) 方法, 沿用上面的 SecurityConfig 类:
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
/**
* 这是一个过期的方法
* 指明密码不用加密
*/
@Bean
PasswordEncoder passwordEncoder(){
return NoOpPasswordEncoder.getInstance();
}
/**
* 定义两个用户,并设置密码和角色
* 从 Spring5.0 开始,密码必须要加密
* 基于内存的用户认证
* @param auth
* @throws Exception
*/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("admin")
.password("123456")
.roles("admin")
.and()
.withUser("user1")
.password("123")
.roles("user");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
// 只有 admin 角色才能访问路径 /admin/**
.antMatchers("/admin/**").hasRole("admin")
// admin 和 user 角色都能访问路径 /user/**
.antMatchers("/user/**").hasAnyRole("admin", "user")
// 其他路径请求,只要是登录用户都可以访问
.anyRequest().authenticated()
.and()
// 配置表单登录
.formLogin()
// 处理登录的 URL
.loginProcessingUrl("/doLogin")
// 与登录相关的请求都可以通过
.permitAll()
.and()
// 关闭 csrf 保护
.csrf().disable();
}
}
通过 http.authorizeRequests().antMatchers("路径").hasRole("角色") ,赋予相应角色的路径访问权限。
HttpSecurity 登录表单配置
仍然沿用上面的configure(HttpSecurity http)
方法。
登录成功
在前后端分离的项目中,登录成功后,后台向前台返回一个 json 字符串,表示登录成功,具体配置如下:
// 登录成功后的处理
.successHandler(new AuthenticationSuccessHandler() {
// authentication 保存了登录成功的用户信息
@Override
public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
// 返回 json 格式的数据
httpServletResponse.setContentType("application/json;charset=utf-8");
PrintWriter writer = httpServletResponse.getWriter();
Map<String, Object> map = new HashMap<>(16);
map.put("status:", 200);
map.put("msg:",authentication.getPrincipal());
writer.write(new ObjectMapper().writeValueAsString(map));
writer.flush();
writer.close();
}
})
效果如下图:
登录失败
登录失败后,后台仍向前台返回一个 json 字符串,并注明登录失败的原因。
登录失败后的具体配置如下:
//登录失败后的处理
.failureHandler(new AuthenticationFailureHandler() {
@Override
public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
httpServletResponse.setContentType("application/json;charset=utf-8");
PrintWriter writer = httpServletResponse.getWriter();
Map<String, Object> map = new HashMap<>(16);
map.put("status:", 401);
if (e instanceof LockedException) {
map.put("msg:", "账户被锁定,登录失败!");
}else if (e instanceof BadCredentialsException){
map.put("msg:", "用户名或密码输入错误,登录失败");
}else if (e instanceof DisabledException){
map.put("msg:", "账户被禁用,登录失败!");
}else if (e instanceof AccountExpiredException){
map.put("msg:", "账户过期,登录失败!");
}else if (e instanceof CredentialsExpiredException){
map.put("msg:", "密码过期,登录失败");
}else {
map.put("msg:","登录失败!");
}
writer.write(new ObjectMapper().writeValueAsString(map));
writer.flush();
writer.close();
}
})
效果如下:
对于登录失败后的各种情况,可以通过查看抽象类 AuthenticationException
的继承关系,获悉所有的异常情况:
注销登录
仍然沿用上面的configure(HttpSecurity http)
方法。
在 .permitAll()
方法后,配置注销登录的信息:
// 与登录相关的请求都可以通过
.permitAll()
// 注销登录的配置
.and()
.logout()
.logoutUrl("/logout")
.logoutSuccessHandler(new LogoutSuccessHandler() {
@Override
public void onLogoutSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
// 返回 json 格式的数据
httpServletResponse.setContentType("application/json;charset=utf-8");
PrintWriter writer = httpServletResponse.getWriter();
Map<String, Object> map = new HashMap<>(16);
map.put("status:", 200);
map.put("msg:","注销登录成功!");
writer.write(new ObjectMapper().writeValueAsString(map));
writer.flush();
writer.close();
}
})
注销登录是一个 get 请求,效果如下:
每天学习一点点,每天进步一点点。
分类:
Spring Security
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从二进制到误差:逐行拆解C语言浮点运算中的4008175468544之谜
· .NET制作智能桌面机器人:结合BotSharp智能体框架开发语音交互
· 软件产品开发中常见的10个问题及处理方法
· .NET 原生驾驭 AI 新基建实战系列:向量数据库的应用与畅想
· 从问题排查到源码分析:ActiveMQ消费端频繁日志刷屏的秘密
· C# 13 中的新增功能实操
· Ollama本地部署大模型总结
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(4)
· 卧槽!C 语言宏定义原来可以玩出这些花样?高手必看!
· langchain0.3教程:从0到1打造一个智能聊天机器人