java解决限制访问指定url

前言

在web项目交付阶段,很多交付的小伙伴们会面临的一个问题就是安全漏洞问题

但不管如何,一旦出现了,既然不能推倒重来,我们还必须要想办法快速补救,下面就本人在项目交付阶段的一点零碎的经验,针对这个问题,做一点技术实现方案的总结

方案1:使用过滤器

这种方式最简单,对大多数程序员来说,也最容易实现,只需要在一个自定义过滤器中,针对所有请求后端服务的url做拦截,对后端所有的URL进行分类,不同的url必须要经过什么样的校验才能通过,这种方式比较简单,就不再做代码层面的展示了

方案2:使用拦截器

先贴上代码

package com.congge.interceptor;  import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView;  import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;  public class MyInterceptor implements HandlerInterceptor {      public static Logger logger = LoggerFactory.getLogger(MyInterceptor.class);      @Override     public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {         logger.info("执行 preHandle:{}",request.getRequestURI());         //TODO 这里可以是token,权限等前置业务的处理......         response.getWriter().write("you have no access");         return false;     }      @Override     public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {         logger.info("执行 preHandle");     }      @Override     public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {         logger.info("执行 afterCompletion");     }  }  
package com.congge.interceptor;  import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;  @Configuration public class MyWebmvcConfig extends WebMvcConfigurationSupport {      @Override     protected void addInterceptors(InterceptorRegistry registry) {         registry.addInterceptor(new MyInterceptor())                 .addPathPatterns("/user/**", "/admin/**", "/account/**")    //哪些路径要拦截                 .excludePathPatterns("/open/api/**");                         //哪些逻辑不需要做拦截     }      /**      * 静态资源的访问      * @param registry      */     @Override     protected void addResourceHandlers(ResourceHandlerRegistry registry) {         registry.addResourceHandler("/static/**")                 .addResourceLocations("classpath:/static/");         registry.addResourceHandler("/templates/**")                 .addResourceLocations("classpath:/templates/");         super.addResourceHandlers(registry);     }  }  

定义一个拦截器,实现HandlerInterceptor接口,在重新的方法中,编写自身校验权限,token等逻辑,如果返回false,请求直接结束,否则可以进入后续的接口资源访问,以文中的配置为例,我们分别访问一下2个接口

java解决限制访问指定url

java解决限制访问指定url
上面这种方式的改造成本比较小,实现难度也很小,可以作为第一选择

方案3:集成shiro

相信很多小伙伴都用过shiro,shiro是一个小巧适用的安全框架,但实际上来说,在和后端项目进行集成时,很多前置的配置工作要做,而且和数据库的权限认证那一套的表结合的很紧密,如果不是在设计之初就集成的话,这个改造的难度和复杂度还是比较大的,慎用

方案4:集成spring-security

一听到spring-security,很多同学开始谈虎色变了,spring-security在后端的框架中算是比较复杂,也比较重型的框架了,学习成本是比较高的,但经过本人的研究发现,如果并不打算完全将spring-security的安全体系替换现有的代码逻辑时,可以借助其部分针对接口资源的权限控制功能,完全可以达到本篇问题的目的,下面通过2种方式来快速说明下

导入security依赖

		<dependency>             <groupId>org.springframework.boot</groupId>             <artifactId>spring-boot-starter-security</artifactId>         </dependency> 

方式1:直接引用上面的依赖之后,在配置文件中做简单的配置即可

#手动设置登录用户名和密码 spring.security.user.name=admin spring.security.user.password=admin 

引入依赖之后,项目启动之后,访问后端接口时,所有的请求都要经过spring-security的默认登录页面,因此上述配置文件中配置的用户名和密码即为登录的用户名和密码

当我们再次访问上面的接口时,就会弹出下面的登录页面

java解决限制访问指定url

输入:root/root,即可正常访问接口了
java解决限制访问指定url
但这种方式的使用场景比较有限,使用的时候请慎重考虑

方式2:使用spring-security的安全配置策略

spring-security集成了很多功能,比如像权限,角色控制等,一般来说,任何系统的登录功能是必不可少的,因此可以借助系统现有的登录登录,再融入spring-security的登录认证即可满足

实现起来,主要包括如下几点,

1)自定义UserDetailsService,即实现UserDetailsService接口

@Configuration("userDetailsService") public class MyUserDetailService implements UserDetailsService {      @Autowired     private UserMapper userMapper;      @Override     public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {         QueryWrapper<MyUser> queryWrapper = new QueryWrapper<>();         queryWrapper.eq("username",username);         MyUser myUser = userMapper.selectOne(queryWrapper);         if(myUser==null){             throw new RuntimeException("该用户不存在");         }         List<GrantedAuthority> roles = AuthorityUtils.commaSeparatedStringToAuthorityList("role");         return new User(username,new BCryptPasswordEncoder().encode(myUser.getPassword()),roles);     } } 

2)自定义配置类,继承WebSecurityConfigurerAdapter,根据需要重写里面的相关方法即可

@Configuration
public class MySecurityConfig extends WebSecurityConfigurerAdapter {

@Autowired private MyUserDetailService userDetailService;  @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception {     auth.userDetailsService(userDetailService).passwordEncoder(password()); }  @Bean public PasswordEncoder password() {     return new BCryptPasswordEncoder(); }  @Override protected void configure(HttpSecurity http) throws Exception {     http.formLogin()                 .loginPage("/login.html")                       //自定义的登录界面                 .loginProcessingUrl("/user/login")              //登录提交的接口                 .defaultSuccessUrl("/zcy/index").permitAll()    //登录成功之后默认的跳转路径             .and().authorizeRequests()                           //自定义受保护的URL资源                 .antMatchers("/","/user/login","/open/api/**")                 .permitAll()                                    //设置那些URL路径可以直接访问,不需要认证                 .anyRequest().authenticated()                   //除了上面其他的URL资源都受保护             .and()                 .csrf().disable();                              //关闭CSRF防护 } 

}

关于上面的这段配置,相信的使用说明,有兴趣的同学可以参考我的专栏文章:spring-security

总体的逻辑就是,在自定义的MyUserDetailService 中,完成登录的业务,只有查到访问资源的请求用户存在才会进入到下一步,当然在这个类中,可以结合现有系统的角色,权限体系做进一步的整合,而MySecurityConfig这个类,控制对访问的URL做保护,规定了哪些URL需要走登录认证,哪些可以不用认证等配置信息

启动项目之后,让我们来做一下测试吧,分别访问一下下面的接口

http://localhost:8081/open/api/user-info
http://localhost:8081/account/get/list

接口1可以直接访问,因为在配置类中对接口直接放行了
java解决限制访问指定url

访问接口2的时候,弹出了如下的自定义登录页面
java解决限制访问指定url
java解决限制访问指定url
在数据库中有这样一个用户,我们输入用户名和密码,就可以访问到该接口了
java解决限制访问指定url

本篇总结了几种常用的限制访问后端URL的方式,希望对看到的小伙伴们有用,本篇到此结束,最后感谢观看!

版权声明:玥玥 发表于 2021-04-26 3:16:44。
转载请注明:java解决限制访问指定url | 女黑客导航