zoukankan      html  css  js  c++  java
  • Spring Security 基础教程 -- HttpSecurity 权限和登录表单配置

    HttpSecurity 权限配置

    主要是通过 HttpSecurity 配置访问控制权限,它仍是继承自 WebSecurityConfigurerAdapter ,重写其中的 configure(HttpSecurity http) 方法, 沿用上面的 SecurityConfig 类

    @Configuration
    public class SecurityConfig extends WebSecurityConfigurerAdapter {
    
        /**
         * 这是一个过期的方法
         * 指明密码不用加密
         */
        @Bean
        PasswordEncoder passwordEncoder(){
            return NoOpPasswordEncoder.getInstance();
        }
    
        /**
         * 定义两个用户,并设置密码和角色
         * 从 Spring5.0 开始,密码必须要加密
         * 基于内存的用户认证
         * @param auth
         * @throws Exception
         */
        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
            auth.inMemoryAuthentication()
                    .withUser("admin")
                    .password("123456")
                    .roles("admin")
                    .and()
                    .withUser("user1")
                    .password("123")
                    .roles("user");
        }
    
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.authorizeRequests()
                    // 只有 admin 角色才能访问路径 /admin/**
                    .antMatchers("/admin/**").hasRole("admin")
                    // admin 和 user 角色都能访问路径 /user/**
                    .antMatchers("/user/**").hasAnyRole("admin", "user")
                    // 其他路径请求,只要是登录用户都可以访问
                    .anyRequest().authenticated()
                    .and()
                    // 配置表单登录
                    .formLogin()
                    // 处理登录的 URL
                    .loginProcessingUrl("/doLogin")
                    // 与登录相关的请求都可以通过
                    .permitAll()
                    .and()
                    // 关闭 csrf 保护
                    .csrf().disable();
        }
    }
    

    通过 http.authorizeRequests().antMatchers("路径").hasRole("角色") ,赋予相应角色的路径访问权限。

    HttpSecurity 登录表单配置

    仍然沿用上面的configure(HttpSecurity http)方法。

    登录成功

    在前后端分离的项目中,登录成功后,后台向前台返回一个 json 字符串,表示登录成功,具体配置如下:

                    // 登录成功后的处理
                    .successHandler(new AuthenticationSuccessHandler() {
                        // authentication 保存了登录成功的用户信息
                        @Override
                        public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
                            // 返回 json 格式的数据
                            httpServletResponse.setContentType("application/json;charset=utf-8");
                            PrintWriter writer = httpServletResponse.getWriter();
                            Map<String, Object> map = new HashMap<>(16);
                            map.put("status:", 200);
                            map.put("msg:",authentication.getPrincipal());
                            writer.write(new ObjectMapper().writeValueAsString(map));
                            writer.flush();
                            writer.close();
                        }
                    })
    

    效果如下图:

    登录失败

    登录失败后,后台仍向前台返回一个 json 字符串,并注明登录失败的原因。

    登录失败后的具体配置如下:

                    //登录失败后的处理
                    .failureHandler(new AuthenticationFailureHandler() {
                        @Override
                        public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
                            httpServletResponse.setContentType("application/json;charset=utf-8");
                            PrintWriter writer = httpServletResponse.getWriter();
                            Map<String, Object> map = new HashMap<>(16);
                            map.put("status:", 401);
                            if (e instanceof LockedException) {
                                map.put("msg:", "账户被锁定,登录失败!");
                            }else if (e instanceof BadCredentialsException){
                                map.put("msg:", "用户名或密码输入错误,登录失败");
                            }else if (e instanceof DisabledException){
                                map.put("msg:", "账户被禁用,登录失败!");
                            }else if (e instanceof AccountExpiredException){
                                map.put("msg:", "账户过期,登录失败!");
                            }else if (e instanceof CredentialsExpiredException){
                                map.put("msg:", "密码过期,登录失败");
                            }else {
                                map.put("msg:","登录失败!");
                            }
                            writer.write(new ObjectMapper().writeValueAsString(map));
                            writer.flush();
                            writer.close();
                        }
                    })
    

    效果如下:

    对于登录失败后的各种情况,可以通过查看抽象类 AuthenticationException的继承关系,获悉所有的异常情况:

    注销登录

    仍然沿用上面的configure(HttpSecurity http)方法。

    .permitAll()方法后,配置注销登录的信息:

                    // 与登录相关的请求都可以通过
                    .permitAll()
                    // 注销登录的配置
                    .and()
                    .logout()
                    .logoutUrl("/logout")
                    .logoutSuccessHandler(new LogoutSuccessHandler() {
                        @Override
                        public void onLogoutSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
                            // 返回 json 格式的数据
                            httpServletResponse.setContentType("application/json;charset=utf-8");
                            PrintWriter writer = httpServletResponse.getWriter();
                            Map<String, Object> map = new HashMap<>(16);
                            map.put("status:", 200);
                            map.put("msg:","注销登录成功!");
                            writer.write(new ObjectMapper().writeValueAsString(map));
                            writer.flush();
                            writer.close();
                        }
                    })
    

    注销登录是一个 get 请求,效果如下:

    每天学习一点点,每天进步一点点。

  • 相关阅读:
    Git一些其它的功能
    怎么利用GitHub
    Git 操作标签的一些命令
    Git标签管理
    Git 多人协作开发
    Git 开发新的功能分支
    Git的Bug分支----临时保存现场git stash
    Git分支管理策略
    2017ICPC南宁 M题 The Maximum Unreachable Node Set【二分图】
    偏序集的最大反链【二分图】
  • 原文地址:https://www.cnblogs.com/youcoding/p/13914535.html
Copyright © 2011-2022 走看看