一、SpringSecurity介绍二、springboot整合Spring Security三、自定义登录逻辑和权限四、自定义成功和失败处理器五、自定义403状态码错误页面六、注解配置
一、SpringSecurity介绍Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架。它提供了一组可以在Spring应用上下文中配置的Bean,充分利用了Spring IoC,DI(控制反转Inversion of Control ,DI:Dependency Injection 依赖注入)和AOP(面向切面编程)功能,为应用系统提供声明式的安全访问控制功能,减少了为企业系统安全控制编写大量重复代码的工作。
二、springboot整合Spring Security1、新建
使用spring initializr 新建springboot项目
记得勾选Spring Security
2、
控制层:
@Controller public class UserController { @RequestMapping public String indexPage() { return "redirect:index.html"; } }
没有指定默认登录页,则使用security默认登陆页面
默认登陆页
用户名默认为 user
密码为 控制台打印的密文
登录后就会跳转到首页
1、持久层
即数据库根据用户名查询用户
@Mapper public interface UserMapper { User findUsername(String username); }
对应的xml
select * from t_user where username = #{username}
2、
配置类
@Configuration public class SecurityConfig extends WebSecurityConfigurerAdapter { @Bean public PasswordEncoder getPw() { return new BCryptPasswordEncoder(); } @Override protected void configure(HttpSecurity http) throws Exception { http.formLogin() .usernameParameter("username") .passwordParameter("password") .loginProcessingUrl("/login") .loginPage("/login.html") .successForwardUrl("/index") .failureForwardUrl("/error"); http.authorizeHttpRequests() .antMatchers("/error.html").permitAll() .antMatchers("/login.html").permitAll() .antMatchers("*.png").permitAll() .regexMatchers(".+[.]png").permitAll() .antMatchers("/member.html").hasAnyAuthority("admin") .antMatchers("/member.html").hasRole("student") .anyRequest().authenticated(); http.csrf().disable(); } }
BCryptPasswordEncoder:密码加密算法,其过程不可逆
相应的登录页面:
注:
1、action中的url地址必须与
.loginProcessingUrl("/login")中url地址相同只有遇到/login时才会被认为是登录2、 .usernameParameter("username")和.passwordParameter("password")中的参数如何跟表单中name属性相同则可省略,否则不可省略
业务层:
@Service public class UserServiceImpl implements UserDetailsService { @Resource private UserMapper userMapper; @Resource private PasswordEncoder passwordEncoder; @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { User user = userMapper.findUserByUsername(username); if (user == null) { throw new UsernameNotFoundException("用户名没有找到"); } String password = passwordEncoder.encode(user.getPassword()); return new org.springframework.security.core.userdetails.User(username, password, AuthorityUtils .commaSeparatedStringToAuthorityList("admin,normal,ROLE_student")); } }
AuthorityUtils .commaSeparatedStringToAuthorityList("admin,normal,ROLE_student")
数据库:
会员页可以正常跳转
将业务层方法改为
return new org.springframework.security.core.userdetails.User(username, password, AuthorityUtils .commaSeparatedStringToAuthorityList("admin,normal0,ROLE_student0"));
配置类不变
首页可以正常跳转
会员页无法正常跳转 报状态码403即权限不足
原因:目前项目都是前后端分离,为了解决跨域问题
.successForwardUrl("/index")和.failureForwardUrl("/error");只能处理post请求
定义成功处理器
public class MyAuthenticationSuccessHandler implements AuthenticationSuccessHandler { private String url; public MyAuthenticationSuccessHandler(String url) { this.url = url; } @Override public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException { response.sendRedirect(url); } }
配置类
http .successHandler(new MyAuthenticationSuccessHandler("http://www.baidu.com")
失败处理器配置相同
即实现AuthenticationFailureHandler接口
查看403状态码
一定不要忘记添加Component注解 交给spring管理
@Component public class MyAccessDeniedHandler implements AccessDeniedHandler { @Override public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException { response.setStatus(HttpServletResponse.SC_FORBIDDEN); response.setHeader("Content-Type","application/json;charset=utf-8"); PrintWriter writer = response.getWriter(); writer.write("{"status":"error","meg":"权限不足,请联系管理员"}"); writer.flush(); writer.close(); } }
在配置类中注入并且配置异常处理
@Autowired private MyAccessDeniedHandler myAccessDeniedHandler; http.exceptionHandling() .accessDeniedHandler(myAccessDeniedHandler);六、注解配置
首先在springboot启动类中开启注解(默认关闭)
@SpringBootApplication @EnableGlobalMethodSecurity(securedEnabled = true,prePostEnabled = true) public class SecuritydemoApplication { public static void main(String[] args) { SpringApplication.run(SecuritydemoApplication.class, args); } }
在控制层中
@PreAuthorize:在登录之前调用此方法 可以省略ROLE_
@Secured:相同作用 但是角色前必须加ROLE_
@Secured("ROLE_student0") @PreAuthorize("hasRole('ROLE_student0')") @RequestMapping("/index") public String indexPage() { return "redirect:index.html"; }
成功跳转
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)