zoukankan      html  css  js  c++  java
  • SpringSecurity基于源码扩展自定义认证失败返回(二十四)

    默认是跳转页面,针对ajax请求我们需要返回json字符串

    自定义认证我认为有2种 一种是登录验证 还有一种是未登录访问需要登录授权的页面

    登录认证

    一般都是使用默认登录或者继承AbstractAuthenticationProcessingFilter方式可以参考上一篇Spring-Security基于源码扩展-自定义登录(二十三)

    设置对应的handle就行了如

       @Override
        protected void configure(HttpSecurity http) throws Exception {
    
            http.authorizeRequests()
                    .anyRequest()
                    .authenticated()
                    .and().rememberMe()//记住登录
                    .tokenRepository(new InMemoryTokenRepositoryImpl())
                    .and()
                    .formLogin()// rm表单的方式
                    .loginPage("/login")//登录页面路径
                    .loginProcessingUrl("/doLogin")
                    //自定义登录请求地址
                    .defaultSuccessUrl("/hello")
                    .successHandler(new AuthenticationSuccessHandler() {
                        @Override
                        public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
                               String result="{\"code\":\"200\",\"message\":\"登录成功\"}";
                                response.getWriter().write(result);
                        }
                    })
                    .failureHandler(new AuthenticationFailureHandler(){
                        @Override
                        public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
                            //可以根据exception 获取我们验证登录时候的异常 定制化抛出异常
                            String result="{\"code\":\"403\",\"message\":\"登录失败\"}";
                            response.getWriter().write(result);
                        }
                    })
                    .usernameParameter("loginName")
                    .passwordParameter("loginPassword")
                    .permitAll(true)//不拦截
                    .and()
                    .csrf()//记得关闭
                    .disable()
                    .sessionManagement().
                    maximumSessions(1)
                    .maxSessionsPreventsLogin(true);
    //
    }

    未登录访问需要登录页面

    Spring-security源码-Filter之FilterSecurityInterceptor(十九) 会进行统一的验证不通过会抛出异常

    Spring-security源码-Filter之ExceptionTranslationFilter(十八)由此过滤器捕获处理

    最终是交给authenticationEntryPoint处理参考源码<>

    初始化是由FormLoginConfigure初始化的

    org.springframework.security.config.annotation.web.configurers.FormLoginConfigurer#loginPage

    public FormLoginConfigurer<H> loginPage(String loginPage) {
            return super.loginPage(loginPage);
        }
        protected T loginPage(String loginPage) {
            setLoginPage(loginPage);
            updateAuthenticationDefaults();
            this.customLoginPage = true;
            return getSelf();
        }
        private void setLoginPage(String loginPage) {
            this.loginPage = loginPage;
            this.authenticationEntryPoint = new LoginUrlAuthenticationEntryPoint(loginPage);
        }

    org.springframework.security.config.annotation.web.configurers.AbstractAuthenticationFilterConfigurer#init

     @Override
        public void init(B http) throws Exception {
            updateAuthenticationDefaults();
            updateAccessDefaults(http);
            //注册
            registerDefaultAuthenticationEntryPoint(http);
        }

    所以我们本质就是只要给ExceptionHandlingConfigurer设置defaultAuthenticationEntryPointFor就行了 

        @SuppressWarnings("unchecked")
        protected final void registerDefaultAuthenticationEntryPoint(B http) {
            registerAuthenticationEntryPoint(http, this.authenticationEntryPoint);
        }
    
        @SuppressWarnings("unchecked")
        protected final void registerAuthenticationEntryPoint(B http, AuthenticationEntryPoint authenticationEntryPoint) {
            //获得ExceptionHandlingConfigurer 也就是初始化我们的ExceptionTranslationFilterConfiger
            ExceptionHandlingConfigurer<B> exceptionHandling = http.getConfigurer(ExceptionHandlingConfigurer.class);
            if (exceptionHandling == null) {
                return;
            }
            //设置
            exceptionHandling.defaultAuthenticationEntryPointFor(postProcess(authenticationEntryPoint),
                    getAuthenticationEntryPointMatcher(http));
        }
        @Override
        protected void configure(HttpSecurity http) throws Exception {
    
            http.authorizeRequests()
                    .anyRequest()
                    .authenticated()
                    .and().rememberMe()//记住登录
                    .tokenRepository(new InMemoryTokenRepositoryImpl())
                    .and()
                    .formLogin()// rm表单的方式
                    .loginPage("/login")//登录页面路径
                    .loginProcessingUrl("/doLogin")
                    //自定义登录请求地址
                    .defaultSuccessUrl("/hello")
                    .successHandler(new AuthenticationSuccessHandler() {
                        @Override
                        public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
                               String result="{\"code\":\"200\",\"message\":\"登录成功\"}";
                                response.getWriter().write(result);
                        }
                    })
                    .failureHandler(new AuthenticationFailureHandler(){
                        @Override
                        public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
                            //可以根据exception 获取我们验证登录时候的异常 丁世华抛出异常
                            String result="{\"code\":\"403\",\"message\":\"登录失败\"}";
                            response.getWriter().write(result);
                        }
                    })
    
                    .usernameParameter("loginName")
                    .passwordParameter("loginPassword")
                    .permitAll(true)//不拦截
                    .and()
                    .exceptionHandling().authenticationEntryPoint(new AuthenticationEntryPoint() {
                @Override
                public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
                    String result="{\"code\":\"403\",\"message\":\"您未登录\"}";
                    response.getWriter().write(result);
                }
            }).and()
                    .csrf()//记得关闭
                    .disable()
                    .sessionManagement().
                    maximumSessions(1)
                    .maxSessionsPreventsLogin(true)
            ;
  • 相关阅读:
    nginx反向代理架构与安装配置(一)
    nginx反向代理部署与演示(二)
    php的opcode缓存原理
    php加速缓存器opcache,apc,xcache,eAccelerator
    php的高性能日志系统 seaslog 的安装与使用
    centos7下源码安装mysql5.7.16
    php 使用html5 XHR2 上传文件 进度显示
    php下ajax的文件切割上传
    php 输出缓冲 Output Control
    php单点登陆简单实现 (iframe方式)
  • 原文地址:https://www.cnblogs.com/LQBlog/p/15557478.html
Copyright © 2011-2022 走看看