springboot+mybatis+spring security
来源:互联网 发布:海尔软件收入 编辑:程序博客网 时间:2024/05/16 12:21
1、不啰嗦,直接上干货
首先新建项目springboot-security导入需要的maven坐标
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.3.0.RELEASE</version> </parent> <properties> <start-class>com.us.example.Application</start-class> <maven.compiler.target>1.8</maven.compiler.target> <maven.compiler.source>1.8</maven.compiler.source> <mybatis.version>3.2.7</mybatis.version> <mybatis-spring.version>1.2.2</mybatis-spring.version> </properties> <dependencies> <!--springboot--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.thymeleaf.extras</groupId> <artifactId>thymeleaf-extras-springsecurity4</artifactId> </dependency> <!--db--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>6.0.5</version> </dependency> <dependency> <groupId>com.mchange</groupId> <artifactId>c3p0</artifactId> <version>0.9.5.2</version> <exclusions> <exclusion> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> </exclusion> </exclusions> </dependency> <!--mybatis--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>${mybatis.version}</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>${mybatis-spring.version}</version> </dependency> </dependencies> <build> <plugins> <!--<!–打依赖包–>--> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>2.3</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> </execution> </executions> </plugin> </plugins> </build>
2、自定义配置FilterSecurityInterceptor,而这个拦截器需要注入自己定义的SecruityMetadataService
3、由2可知新建MySecruityMetadataService,这个类需要实现FilterInvocationSecurityMetadataSource接口,在这个类中有主要的三部分:第一:加载所有的权限列表;第二:取到当前访问的路径;第三:拿到的路径为访问路径的权限列表
@Servicepublic class MySecruityMetadataService implements FilterInvocationSecurityMetadataSource { @Autowired private PermissionDao permissionDao; private HashMap<String, Collection<ConfigAttribute>> map =null; /** * 加载资源,初始化资源变量 */ public void loadResourceDefine(){ map = new HashMap<>(); Collection<ConfigAttribute> array; ConfigAttribute cfg; List<Permission> permissions = permissionDao.findAll(); for(Permission permission : permissions) { array = new ArrayList<>(); cfg = new SecurityConfig(permission.getName()); array.add(cfg); map.put(permission.getUrl(), array); } } @Override public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException { if(map ==null) loadResourceDefine(); HttpServletRequest request = ((FilterInvocation) object).getHttpRequest(); AntPathRequestMatcher matcher; String resUrl; for(Iterator<String> iter = map.keySet().iterator(); iter.hasNext(); ) { resUrl = iter.next(); matcher = new AntPathRequestMatcher(resUrl); if(matcher.matches(request)) { return map.get(resUrl); } } return null; } @Override public Collection<ConfigAttribute> getAllConfigAttributes() { return null; } @Override public boolean supports(Class<?> clazz) { return true; }}
4、回退到第二步,注入自己的MySecruityMetadataService,执行过滤器(调用父类,父类中会执行)
@Servicepublic class MyFilterSecurityInterceptor extends AbstractSecurityInterceptor implements Filter { @Autowired private FilterInvocationSecurityMetadataSource securityMetadataSource; @Autowired public void setMyAccessDecisionManager(MyAccessDecisionManager myAccessDecisionManager) { super.setAccessDecisionManager(myAccessDecisionManager); } @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { FilterInvocation fi = new FilterInvocation(request, response, chain); invoke(fi); } public void invoke(FilterInvocation fi) throws IOException, ServletException { //fi里面有一个被拦截的url //里面调用MyInvocationSecurityMetadataSource的getAttributes(Object object)这个方法获取fi对应的所有权限 //再调用MyAccessDecisionManager的decide方法来校验用户的权限是否足够 InterceptorStatusToken token = super.beforeInvocation(fi); try { //执行下一个拦截器 fi.getChain().doFilter(fi.getRequest(), fi.getResponse()); } finally { super.afterInvocation(token, null); } } @Override public void destroy() { } @Override public Class<?> getSecureObjectClass() { return FilterInvocation.class; } @Override public SecurityMetadataSource obtainSecurityMetadataSource() { return this.securityMetadataSource; }}
5、配置自定义的MyUserDetailsService,查询出此用户的所有访问权限
@Servicepublic class CustomUserService implements UserDetailsService { //自定义UserDetailsService 接口 @Autowired UserDao userDao; @Autowired PermissionDao permissionDao; public UserDetails loadUserByUsername(String username) { SysUser user = userDao.findByUserName(username); if (user != null) { List<Permission> permissions = permissionDao.findByAdminUserId(user.getId()); List<GrantedAuthority> grantedAuthorities = new ArrayList <>(); for (Permission permission : permissions) { if (permission != null && permission.getName()!=null) { GrantedAuthority grantedAuthority = new SimpleGrantedAuthority(permission.getName()); grantedAuthorities.add(grantedAuthority); } } return new User(user.getUsername(), user.getPassword(), grantedAuthorities); } else { throw new UsernameNotFoundException("admin: " + username + " do not exist!"); } }}
6、在自定义的MyAccessDecisionManager中判断自己通过用户名查询出来的权限列表中是否包含通过访问路径查询出来的权限。
@Servicepublic class MyAccessDecisionManager implements AccessDecisionManager { @Override public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes) throws AccessDeniedException, InsufficientAuthenticationException { if(null== configAttributes || configAttributes.size() <=0) { return; } ConfigAttribute c; String needRole; for(Iterator<ConfigAttribute> iter = configAttributes.iterator(); iter.hasNext(); ) { c = iter.next(); needRole = c.getAttribute(); for(GrantedAuthority ga : authentication.getAuthorities()) { if(needRole.trim().equals(ga.getAuthority())) { return; } } } throw new AccessDeniedException("no right"); } @Override public boolean supports(ConfigAttribute attribute) { return true; } @Override public boolean supports(Class<?> clazz) { return true; }}
7、页面展示控制
<div sec:authorize="hasRole('ROLE_ADMIN')"> <!-- 用户类型为ROLE_ADMIN 显示 --> <p class="bg-info">恭喜您,您有 ROLE_ADMIN 权限 </p> </div>
8、最后还需要一个配置类继承WebSecurityConfigurerAdapter,实现对请求进行过滤
@Configuration@EnableWebSecurity@EnableGlobalMethodSecurity(prePostEnabled = true) //开启方法级别的权限注解public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private MyFilterSecurityInterceptor myFilterSecurityInterceptor; @Autowired UserDetailsService customUserService; @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(customUserService); //user Details Service验证 } @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/css/**").permitAll() .anyRequest().authenticated() //任何请求,登录后可以访问 .and() .formLogin() .loginPage("/login") .defaultSuccessUrl("/") .failureUrl("/login?error") .permitAll() //登录页面用户任意访问 .and() .logout().permitAll(); //注销行为任意访问 http.addFilterBefore(myFilterSecurityInterceptor, FilterSecurityInterceptor.class); }}
8、开启方法级别的注解权限(第七配置类的@EnableGlobalMethodSecurity(prePostEnabled = true) //开启方法级别的权限注解)使用方式
@RequestMapping("/admin") @ResponseBody @PreAuthorize("hasAnyRole('ROLE_ADMIN')") public String hello(){ return "hello admin"; }
https://git.oschina.net/itheima_liang/springboot-mybatis-springsecurity.wiki.git
----------------ITteenager
阅读全文
0 0
- springboot+mybatis+spring security
- SpringBoot整合Spring Security和Mybatis验证
- springboot+mybatis实现security
- SpringBoot - Spring Security学习
- SpringBoot~Spring Security入门
- springboot整合spring-security
- springboot集成spring security初探
- SpringBoot系列—mybatis和spirng security
- springboot【7】安全控制之Spring Security
- Spring security实战(2)-----搭建SpringBoot
- springboot spring-security 集成微信登录
- SpringBoot:spring boot集成mybatis
- springboot+spring+springmvc+mybatis详解
- spring MVC+mybatis+spring security笔记<一>
- spring MVC+mybatis+spring security笔记<二>
- springboot+spring+spring+mybatis+ajxa(ssmaboot)
- springboot+spring+spring+mybatis+ajxa(ssmaboot)
- Springboot security
- Servlet的请求转发和重定向转发
- JavaWeb学习总结(二十二)——基于Servlet+JSP+JavaBean开发模式的用户登录注册
- java判断字符串是否为数字或中文或字母
- Android内存优化之OOM
- JAVA设计模式之工厂模式(简单工厂模式+工厂方法模式)
- springboot+mybatis+spring security
- 36 日志管理
- Ubuntu卸载软件
- JAVA设计模式之单例模式
- 依赖
- Java除了基本类型,其它都是引用传值,传值是改变变量引用的方向
- 第一次用python连接mysql数据库
- 深度学习--caffe(1)
- 定时操作,公司里叫定时任务调度,我用Quartz(一)