springboot+security框架整合

springboot项目搭建大家可以去请教度娘,有很多文章,这里主要讲解springboot和security安全框架的集成,因为springmvc跟security集成中,大部分都是采用配置文件的形式,本例中完全没用配置文件,配置文件的方式写起来比较省事,但是比较难懂,导致我在写这个的时候网上搜的资料也不多,很难搞,好不容易弄好了,怕自己忘记,特此记录一下。

表格部分:分为五个表格

sys_user 

sys_role

sys_menu

sys_user_role

sys_role_menu

分表创建实体Bean,数据访问层是用的hibernate,具体代码可参见附件

安全框架配置部分

配置文件那种的方式最主要的是配置文件,而不用配置文件最主要的就是自定义的去实现WebSecurityConfigurerAdapter类,大体的思路为: 
1、WebSecurityConfig===》WebSecurityConfigurerAdapter(主要配置文件) 
2、MyAuthenticationProvider==》AuthenticationProvider(自定义验证用户名密码) 
3、CustomUserDetailsService==》UserDetailsService(MyAuthenticationProvider需要调用) 
4、mySecurityFilter==》AbstractSecurityInterceptor 、Filter(自定义的过滤器) 
5、FilterSourceMetadataSource==》FilterInvocationSecurityMetadataSource(过滤器调用,过滤器加载资源) 
6、MyAccessDecisionManager ==》AccessDecisionManager(过滤器调用,验证用户是否有权限访问资源)

下面是WebSecurityConfig

package com.zy.configuration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.encoding.Md5PasswordEncoder;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.servlet.configuration.EnableWebMvcSecurity;
import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;
import org.springframework.stereotype.Service;/*** @Author zhang* @create 2017-07-14-15:51* @desc ${DESCRIPTION}**/
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)//开启security注解
public class WebSecurityConfig  extends WebSecurityConfigurerAdapter {@Autowiredprivate MyAuthenticationProvider authenticationProvider;@Autowiredprivate MySecurityFilter mySecurityFilter;@Overridepublic AuthenticationManager authenticationManagerBean() throws Exception {return super.authenticationManagerBean();}@Overrideprotected void configure(HttpSecurity http) throws Exception {//允许所有用户访问"/"和"/home"http.addFilterBefore(mySecurityFilter, FilterSecurityInterceptor.class)//在正确的位置添加我们自定义的过滤器.csrf().disable().authorizeRequests().antMatchers("/", "/home","403").permitAll()//访问:/home 无需登录认证权限//其他地址的访问均需验证权限.anyRequest().authenticated()//其他所有资源都需要认证,登陆后访问.and().formLogin()//指定登录页是"/login".loginPage("/login").defaultSuccessUrl("/index")//登录成功后默认跳转到"/hello"
//                    .failureUrl("/403").permitAll()//.successHandler(loginSuccessHandler())//code3.and().logout().logoutSuccessUrl("/")//退出登录后的默认url是"/home".permitAll().and().rememberMe()//登录后记住用户,下次自动登录,数据库中必须存在名为persistent_logins的表.tokenValiditySeconds(1209600);  ;}@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {auth.authenticationProvider(authenticationProvider);auth.userDetailsService(customUserDetailsService()).passwordEncoder(passwordEncoder());}@Overridepublic void configure(WebSecurity web) throws Exception {web.ignoring().antMatchers("/resources/**");//可以仿照上面一句忽略静态资源}//    @Autowired
//    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
//        auth.authenticationProvider(authenticationProvider);
//    }/*** 设置用户密码的加密方式为MD5加密* @return*/@Beanpublic Md5PasswordEncoder passwordEncoder() {return new Md5PasswordEncoder();}/*** 自定义UserDetailsService,从数据库中读取用户信息* @return*/@Beanpublic CustomUserDetailsService customUserDetailsService(){return new CustomUserDetailsService();}
//
}

类MyAuthenticationProvider 自定义的用户名密码验证,调用了loadUserByUsername方法

@Component
public class MyAuthenticationProvider implements AuthenticationProvider {@Autowiredprivate CustomUserDetailsService customUserDetailsService;@Overridepublic Authentication authenticate(Authentication authentication) throws AuthenticationException{String username = authentication.getName();String password = (String) authentication.getCredentials();UserDetails user = customUserDetailsService.loadUserByUsername(username);if(user == null){throw new BadCredentialsException("用户没有找到");}//加密过程在这里体现if (!password.equals(user.getPassword())) {System.out.print("密码错误");throw new BadCredentialsException("密码错误");}Collection<? extends GrantedAuthority> authorities = user.getAuthorities();return new UsernamePasswordAuthenticationToken(user, password, authorities);}public boolean supports(Class<?> var1){return true;}
}

类CustomUserDetailsService 实现 UserDetailsService

@Transactional(propagation = Propagation.REQUIRED, readOnly = true)
@Service
public class CustomUserDetailsService implements UserDetailsService {@Autowiredprivate UserService userService;@Autowiredprivate ActionRepository actionRepository;public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException{try {UserBean user = userService.findUserByName(userName);if(null == user){throw new UsernameNotFoundException("UserName " + userName + " not found");}// SecurityUser实现UserDetails并将SUser的Email映射为usernameList<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();for (RoleBean ur : user.getRoleBeans()) {String name = ur.getRoleName();GrantedAuthority grantedAuthority = new SimpleGrantedAuthority(name);authorities.add(grantedAuthority);}return new User(user.getUsername(),user.getPassword(),authorities);}catch ( Exception e){e.printStackTrace();return null;}}} 

类MySecurityFilter 自定义过滤器,拦截器我本来没有自定义,但是会有问题一些访问的资源什么的没有办法过滤掉。

package com.zy.configuration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.SecurityMetadataSource;
import org.springframework.security.access.intercept.AbstractSecurityInterceptor;
import org.springframework.security.access.intercept.InterceptorStatusToken;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.web.FilterInvocation;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import javax.servlet.*;
import java.io.IOException;/*** @Author toplion* @create 2017-08-03-17:00* @desc ${DESCRIPTION}**/
@Service
public class MySecurityFilter extends AbstractSecurityInterceptor implements Filter{@Autowiredprivate FilterSourceMetadataSource filterInvocationSource;@Autowiredprivate MyAccessDecisionManager myAccessDecisionManager;@Autowiredprivate AuthenticationManager authenticationManager;@PostConstructpublic void init(){super.setAuthenticationManager(authenticationManager);super.setAccessDecisionManager(myAccessDecisionManager);}public void doFilter( ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException{FilterInvocation fi = new FilterInvocation( request, response, chain );invoke(fi);}public Class<? extends Object> getSecureObjectClass(){return FilterInvocation.class;}public void invoke( FilterInvocation fi ) throws IOException, ServletException{System.out.println("filter..........................");InterceptorStatusToken  token = super.beforeInvocation(fi);try{fi.getChain().doFilter(fi.getRequest(), fi.getResponse());}finally{super.afterInvocation(token, null);}}@Overridepublic SecurityMetadataSource obtainSecurityMetadataSource(){System.out.println("filtergergetghrthetyetyetyetyj");return this.filterInvocationSource;}public void destroy(){System.out.println("filter===========================end");}public void init( FilterConfig filterconfig ) throws ServletException{System.out.println("filter===========================");}
}

类FilterSourceMetadataSource

@Service
public class FilterSourceMetadataSource implements FilterInvocationSecurityMetadataSource {private static Map<String, Collection<ConfigAttribute>> resourceMap = new HashMap<String, Collection<ConfigAttribute>>();private ActionRepository menuService;private RequestMatcher pathMatcher;@Autowiredpublic FilterSourceMetadataSource(ActionRepository repository) {this.menuService = repository;loadResourcePermission();}/*** 返回所请求资源所需要的权限* 针对资源的URL* @param o* @return* @throws IllegalArgumentException*/@Overridepublic Collection<ConfigAttribute> getAttributes(Object o) throws IllegalArgumentException {Iterator<String> resourceUrls = resourceMap.keySet().iterator();while (resourceUrls.hasNext()) {String resUrl = resourceUrls.next();System.out.print("**********************************"+resUrl);if(null == resUrl || resUrl.isEmpty()) {continue;}pathMatcher = new AntPathRequestMatcher(resUrl);if (pathMatcher.matches(((FilterInvocation) o).getRequest())) {Collection<ConfigAttribute> configAttributes = resourceMap.get(resUrl);return configAttributes;}}return null;}/*** 获取所有配置权限* @return*/@Overridepublic Collection<ConfigAttribute> getAllConfigAttributes() {Collection<Collection<ConfigAttribute>> cacs = resourceMap.values();Collection<ConfigAttribute> cac = new HashSet<ConfigAttribute>();for (Collection<ConfigAttribute> c: cacs) {cac.addAll(c);}return cac;}@Overridepublic boolean supports(Class<?> aClass) {return true;}/*** 加载资源的权限*/private void loadResourcePermission() {loadMenuPermisson();}/*** 加载菜单的权限*/private void loadMenuPermisson() {List<ActionBean> menus = menuService.findAll();for (ActionBean menu: menus) {List<ConfigAttribute> configAttributes = new ArrayList<ConfigAttribute>();
//            MenuEntity currMenu = menuService.getMenuById(menu.getMenuId());Hibernate.initialize(menu);ConfigAttribute configAttribute = new SecurityConfig(menu.getMenuCode());configAttributes.add(configAttribute);if(null != resourceMap.get(menu.getMenuUrl())) {resourceMap.get(menu.getMenuUrl()).addAll(configAttributes);} else {resourceMap.put(menu.getMenuUrl(), configAttributes);}}System.out.println(resourceMap);}}

类MyAccessDecisionManager

@Service
public class MyAccessDecisionManager implements AccessDecisionManager {/*** 验证用户是否有权限访问资源* @param authentication* @param o* @param configAttributes* @throws AccessDeniedException* @throws InsufficientAuthenticationException*/@Overridepublic void decide(Authentication authentication, Object o, Collection<ConfigAttribute> configAttributes) throws AccessDeniedException, InsufficientAuthenticationException {/*允许访问没有设置权限的资源*/if(configAttributes == null) {return;}/*一个资源可以由多个权限访问,用户拥有其中一个权限即可访问该资源*/Iterator<ConfigAttribute> configIterator = configAttributes.iterator();while (configIterator.hasNext()) {ConfigAttribute configAttribute = configIterator.next();String needPermission = configAttribute.getAttribute();for(GrantedAuthority ga : authentication.getAuthorities()) {if(needPermission.equals(ga.getAuthority())) {return;}}}throw new AccessDeniedException("没有权限访问");}/*** 特定configAttribute的支持* @param configAttribute* @return*/@Overridepublic boolean supports(ConfigAttribute configAttribute) {/*支持所有configAttribute*/return true;}/*** 特定安全对象类型支持* @param aClass* @return*/@Overridepublic boolean supports(Class<?> aClass) {/*支持所有对象类型*/return true;}
}

springboot+security框架整合相关推荐

  1. SpringBoot后端框架整合前端Vue系统框架

    SpringBoot后端框架整合前端Vue系统框架 本节内容服务于SpringBoot + Vue 搭建 JavaWeb 增删改查项目. 在IDEA中整合前后端框架,实现前后端分离,人不分离,方便项目 ...

  2. Nginx+Springboot+Security+CAS 整合方案-XML 实现SSO客户端

    javaconfig版本: https://www.cnblogs.com/question-sky/p/7068511.html 以下使用的是SpringBoot 2.1.1进行测试 0 Maven ...

  3. springboot+security整合(1)

    说明 springboot 版本 2.0.3 源码地址:点击跳转 系列 springboot+security 整合(1) springboot+security 整合(2) springboot+s ...

  4. springboot 2.x 整合 shiro 权限框架

    序 在实际项目中,经常需要用到角色权限区分,以此来为不同的角色赋予不同的权利,分配不同的任务.比如,普通用户只能浏览:会员可以浏览和评论:超级会员可以浏览.评论和看视频课等:实际应用场景很多.毫不夸张 ...

  5. 采用SpringBoot、MyBatis-Plus 、Security框架,开发的一套权限系统,实现前后端分离,完善的代码生成机制

    项目说明 harry 采用SpringBoot.MyBatis-Plus .Security框架,开发的一套权限系统,实现前后端分离,完善的代码生成机制.Harry Gitee地址 harry-vue ...

  6. ssm框架整合_框架整合战斗压缩粮篇SpringCloud+SpringBoot+SSM

    各位小伙伴今天又敲了多少Bug了,今天改Bug又花了多长时间啦,我们每天就是敲Bug,敲完改,改完敲,习惯就好啦,心态摆正.Debug起来!!! 上次是Dubbo整合,今天终结篇Cloud整合,不要废 ...

  7. IDEA创建一个springboot项目(三)整合swagge接口测试框架

    我是在上一篇的demo基础上增加的,上一篇地址:springboot项目(二)整合TKMytis框架 一:认识Swagger Swagger 是一个规范和完整的框架,用于生成.描述.调用和可视化 RE ...

  8. 使用SpringBoot框架和SpringSecurity框架整合出现because its MIME type ('text/html') is not executable

    前端页面出现: Refused to execute script from 'http://localhost:8080/login' because its MIME type ('text/ht ...

  9. 视频教程-SpringBoot+Security+Vue前后端分离开发权限管理系统-Java

    SpringBoot+Security+Vue前后端分离开发权限管理系统 10多年互联网一线实战经验,现就职于大型知名互联网企业,架构师, 有丰富实战经验和企业面试经验:曾就职于某上市培训机构数年,独 ...

最新文章

  1. WINDOWS SERVER 2003 之域重命名
  2. 【Scratch】青少年蓝桥杯_每日一题_3.07_画金字塔
  3. AAAI 2021最佳论文亚军:Attention+积分梯度=归因解释新方法
  4. C语言const专题
  5. gridview 动态数据操作
  6. C# 创建一个简单的WebApi项目
  7. 设计模式C++实现--Observer模式
  8. caffeine 缓存_使用Caffeine和Spring Boot的多个缓存配置
  9. PHP 性能分析: Xhprof Xhgui
  10. adb shell命令_[Android]adb的使用
  11. PXE自动化安装系统工具介绍与部署
  12. 单个正态总体均值的区间估计_统计概率之误差思维:置信区间
  13. 去年出货的工业机器人,超过1/3都跑来了中国
  14. SpringCloud中 Feign结合Hystrix断路器开发。
  15. WPF TextBox/TextBlock 文本超出显示时,文本靠右显示
  16. 【离散数学】集合论 第三章 集合与关系(1) 集合的概念与表示
  17. List集合去重的几种方法
  18. 如何一键重装Win7系统 便捷重装Win7系统教程
  19. linux安装程序企鹅,在Linux上安装小企鹅输入法
  20. 无人驾驶入门——2D检测 基于图片的检测算法(四)

热门文章

  1. 为什么本地硬盘无法启动计算机,win10专业版系统本地磁盘打不开怎么办?
  2. php判断值是否为空然后定义,判断php变量是不是定义,是否为空
  3. 【C语言】这是我能想到的最难的题了
  4. 计算机网络(六)——连接到Internet
  5. 数据结构之栈与递归的应用(汉诺塔递归解法)
  6. tcp协议栈优化1-增加TCP初始拥塞窗口
  7. php位值,解决 PHP 中 usort 在值相同时改变原始位置的问题
  8. UI自动化测试POM设计之-maven工程
  9. org.springframework.hateoas.mvc.ControllerLinkBuilder之ClassNotFoundException的错误
  10. 如何成为一名好的研究生