V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
liuzhaowei55
V2EX  ›  程序员

Spring security 为啥那么难。。。

  •  
  •   liuzhaowei55 ·
    ysbjlzlx · 2018-11-27 18:03:57 +08:00 · 6043 次点击
    这是一个创建于 2173 天前的主题,其中的信息可能已经有所发展或是发生改变。

    想用 Spring Boot + Spring security 配合做一个 REST API 的后端服务,两天了,还没达到自己想要的效果。
    现在有一个需求就是 org.springframework.security.access.AccessDeniedException 这个异常应该怎么处理?全局异常抓不到,httpSecurity.getConfigurer(ExceptionHandlingConfigurer.class).accessDeniedHandler(new CustomAccessDeniedHandler()); 自定义一个 handler 也不起作用,有大佬可以给个相关文档吗?

    第 1 条附言  ·  2018-11-28 16:39:36 +08:00

    https://www.cnblogs.com/xz816111/p/8528896.html
    https://segmentfault.com/a/1190000012560773
    首先,特别感谢大家没有 DISS 我是伸手党,现在论坛问个问题特害怕这个了。
    上边两篇文章,让我对 Spring Security 的运行,有了一个更完整一点的概念,有需要的可以看下。
    然后我说一下,现在我的解决方案,因为这里有一些问题,还是需要大家的帮助。

    • 自定义以下几个类:
    // 用来处理抛出的 AuthenticationException
    class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint
    // 用来获取前端传过来的 Token,交由 AuthenticationProvider 校验。(重要)
    class CustomAuthenticationFilter extends OncePerRequestFilter
    // 用户装载 Token,和检出的用户 UserDetails
    class CustomAuthenticationToken implements Authentication
    // 校验 Token 的正确性
    class CustomAuthenticationProvider implements AuthenticationProvider 
    
    
    • 下边是 class WebSecurityConfig extends WebSecurityConfigurerAdapter 配置
        @Override
        protected void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
            authenticationManagerBuilder
                    .authenticationProvider(customAuthenticationProvider);
        }
    
        @Override
        protected void configure(HttpSecurity httpSecurity) throws Exception {
            httpSecurity.authorizeRequests().anyRequest().authenticated();
            httpSecurity.headers().cacheControl();
            httpSecurity.csrf().disable();
            httpSecurity.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
            httpSecurity.addFilterAfter(new CustomAuthenticationFilter(authenticationManager()), AnonymousAuthenticationFilter.class);
            httpSecurity.exceptionHandling().authenticationEntryPoint(new CustomAuthenticationEntryPoint());
        }
    
        @Override
        public void configure(WebSecurity webSecurity) throws Exception {
            webSecurity.ignoring()
                    .antMatchers(HttpMethod.OPTIONS, "/**")
                    .antMatchers("/auth/login")
            super.configure(webSecurity);
        }
    
    第 2 条附言  ·  2018-11-28 16:40:33 +08:00

    好了,基本说完现在情况了,现在这个配置基本可以满足 REST 的使用了,但是还有两个问题,比较疑惑

    • httpSecurity.addFilterAfter(new CustomAuthenticationFilter(authenticationManager()), AnonymousAuthenticationFilter.class); 这样添加自定义 Filter ,Filter 无法根据 httpSecurity.requestMatchers() 的设置,自动跳过无需登录的 uri,我这个添加 Filter 的方法正确吗?
    • CustomAuthenticationEntryPoint 只能捕获到 class org.springframework.security.authentication.InsufficientAuthenticationException 这样一个 Exception,运行中分别抛出的 AuthenticationCredentialsNotFoundExceptionBadCredentialsException 这两个 Exception 只会在控制台 DEBUG 输出,无法捕获到,我应该怎么处理。
    7 条回复    2018-11-28 11:28:41 +08:00
    Mrbird
        1
    Mrbird  
       2018-11-27 18:33:39 +08:00   ❤️ 1
    httpSecurity.exceptionHandling().accessDeniedHandler(accessDeniedHandler())

    我这样设置是有效的。
    tomoya92
        2
    tomoya92  
       2018-11-27 18:52:20 +08:00 via iPhone
    确实很难,还是换 shiro 吧,要简单的多
    qwx
        3
    qwx  
       2018-11-27 19:13:21 +08:00   ❤️ 2
    实际上 spring security 要是了解了他的整个处理链就不难了,一开始确实恶心,做了个 jwt 的应用就全理解了,用起来也爽很多。我也是楼上的 httpSecurity 中配置的,运行正常。
    diaolizhi
        4
    diaolizhi  
       2018-11-27 20:25:42 +08:00 via Android
    @qwx 请问有什么资料推荐吗
    br00k
        5
    br00k  
       2018-11-28 00:49:15 +08:00
    jhipster 了解下
    hengo
        6
    hengo  
       2018-11-28 03:14:41 +08:00 via iPhone
    我也在做和你同样的操作,不是很会用 security
    qinxi
        7
    qinxi  
       2018-11-28 11:28:41 +08:00   ❤️ 1
    我是这样的...httpSecurity.exceptionHandling().authenticationEntryPoint(new MyAuthenticationEntryPoint())
    .accessDeniedHandler(new MyAccessDeniedHandlerImpl())
    .and().addFilterBefore(new JWTAuthenticationFilter(),
    UsernamePasswordAuthenticationFilter.class)
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2251 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 31ms · UTC 16:08 · PVG 00:08 · LAX 08:08 · JFK 11:08
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.