Spring Boot Security 权限
这两天研究了一下权限管理框架。。
查阅资料的过程中,JAVA中常用的安全框架有Shiro和Spring Security。Shiro比Spring Security学习起来更加简单,功能够用。而这两天的学习中,就我自己的体会而言,学习Spring Security还是有一定难度的。虽然它的扩展性非常的好,我们可以重载它默认的类,重写方法,达到我们要的结果。
本来这篇文章是准备记录一下搭建一个权限系统的完整过程的,但因为能力有限,对security了解还不是很透彻,这里就只贴出我查阅资料过程中,觉得写得好的一些博客,和一些自己的观点和看法。也方便日后自己查阅。
安全框架Shiro和Spring Security比较
权限 + 认证框架组合
Spring Boot + Spring Security + JWT
Spring Boot + Spring Security + Oauth2
好的博客教程
基于springboot的security机制(自定义登录页面+基于内存身份认证+基于mybatis身份认证)
Spring Boot中使用 Spring Security 构建权限系统
最后还是贴上我自己的demo
Git地址:https://github.com/xiangjiangcheng/spring-boot-demo1.git
目录截图:
demo中只是简单实现了用户登录才能访问对应资源 + 简单的权限控制,并没有结合数据库
实现权限管理。大致的流程如下图所示:
这里说的简单权限控制指的是:
当你访问一个controller的时候,会被拦截,提示登录。登录成功后,判断该用户是否有权访问该controller。
实现方式是在配置文件手动配置,这种方式很不灵活。网上说在方法上面加注解,来控制权限,亦是如此。维护起来很麻烦。
具体代码查看demo中BrowerSecurityConfig.java
配置文件
/**
* 重写该方法,设定用户访问权限
* 用户身份可以访问 订单相关API
* */
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/orders/**").hasAnyRole("USER", "ADMIN") //用户权限,管理员权限
.antMatchers("/user/**").hasRole("ADMIN") //管理员权限
.anyRequest().authenticated() //任何请求,登录后可以访问
.and()
.formLogin()
.loginPage("/login") //跳转登录页面的控制器,该地址要保证和表单提交的地址一致!
.successHandler(new AuthenticationSuccessHandler() {
// 通过SecurityContextHolder获取目前登录的用户信息,然后将其放到session中(不建议如此处理)然后将页面重定向到首页中。
@Override
public void onAuthenticationSuccess(HttpServletRequest arg0, HttpServletResponse arg1, Authentication arg2)
throws IOException, ServletException {
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
if (principal != null && principal instanceof UserDetails) {
UserDetails user = (UserDetails) principal;
System.out.println("loginUser:"+user.getUsername());
//维护在session中
arg0.getSession().setAttribute("userDetail", user);
arg1.sendRedirect("/home");
}
}
})
//失败处理
.failureHandler(new AuthenticationFailureHandler() {
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException authenticationException)
throws IOException, ServletException {
System.out.println("error:"+authenticationException.getMessage());
response.sendRedirect("/login");
}
})
.permitAll()
.and()
.logout()
.permitAll() //注销行为任意访问
.and()
.csrf().disable(); //暂时禁用CSRF,否则无法提交表单
}
实现Restful接口 不拦截
BrowerSecurityConfig.java
配置文件对应地方加入如下代码
// 对于获取token的rest api要允许匿名访问
.antMatchers("/auth/**").permitAll()
.antMatchers("/druid/**").permitAll()
.antMatchers(HttpMethod.GET, "/entries/**", "/articles/**").permitAll()
// 除上面外的所有请求全部需要鉴权认证
.anyRequest().authenticated();
注意
1.配置文件里面配置了每个controller对应的权限时,如
.antMatchers("/orders/**").hasAnyRole("USER", "ADMIN") //用户权限
.antMatchers("/user/**").hasRole("ADMIN") //管理员权限
那么数据库里面,对应的值必须是ROLE_USER
,ROLE_ADMIN
2.开发过程中,可以开启secutity的debug模式,代码如下
// 使用debug模式
@EnableWebSecurity(debug = true)
// @EnableWebSecurity
这样,就能看到每次请求的详细信息,以及都经过哪些拦截器拦截!
小结
在我看来,web开发过程中,只要涉及到用户登录,再有权限分配这些功能,那么一套完整的权限管理系统已经是必不可少的了。
以往传统的权限系统,都是自己写一些拦截器,简单的实现了权限管理。说简单一点就是,写一个全局的拦截器,请求来之后,判断session中是否存在该用户,若session中没有该用户信息,则该资源不让访问,跳转到登录页面!
如果是使用权限框架,最重要的还是阅读文档和实践。只有了解了它的一些基础的原理,才能举一反三。
可以使用打断点的模式,了解框架到底是怎么在工作的,这能更快的了解他的工作流程。
很多关于Security的博客都写得不是很清楚。所谓的不清楚,也就是当我把一篇博客看完了后,我竟然没有一点思绪,还是不晓得从哪里入手。。。估计是我个人能力问题。
后面有时间再慢慢研究下使用框架实现权限和认证~~