HttpSecurity的配置以及登录表单的详细配置和注销登录的配置

/**
 * @Author fei
 * @Date 2021/1/2 3:43 下午
 *
 * @Configuration用于定义配置类,定义的配置类可以替换xml文件,一般和@Bean注解联合使用。
 * @Configuration注解主要标注在某个类上,相当于xml配置文件中的<beans>
 * @Bean注解主要标注在某个方法上,相当于xml配置文件中的<bean>
 */

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    /**
     * 必须要有这个实例  NoOpPasswordEncoder.getInstance()  这是一个过期的方法。
     * @return
     */
    @Bean
    PasswordEncoder passwordEncoder(){
        return NoOpPasswordEncoder.getInstance();//获取这个不加密的实例  为了下面的用户名对应的密码不加密   直接123就可以登录
    }

    /**
     * 设置用户和密码 以及角色
     * @param auth
     * @throws Exception
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        //在内存中配置密码
        auth.inMemoryAuthentication()
                .withUser("ppf").password("123").roles("admin")
                .and()
                .withUser("ask").password("123").roles("user");
    }


    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests() //开启授权方法
                .antMatchers("/admin/**").hasRole("admin")  //匹配器,在/admin/**这个地址要进行权限配置,赋予一个角色 admin
                //.antMatchers("user/**").hasAnyRole("admin","user")  //hasAnyRole  表示具备这两个角色其中一个就可以
                .antMatchers("/user/**").access("hasAnyRole('user','admin')")  //这个和上面的一个意思
                .anyRequest().authenticated()  //anyRequest 表示其他没有需要授权的地址,登录之后就能访问。 authenticated  已验证的 登录之后能访问
                .and()
                .formLogin()  //上面配完之后呢,下面还需要配置表单登录
                .loginProcessingUrl("/doLogin")  //表示处理登录请求的url  这个配不配都可以,主要是方便用postman 来测试接口时用
                .loginPage("/login") //这个表示需要登录,则跳转到/login这个url  一般前后端分离 不需要配置这个
                .usernameParameter("uname") //这个表示 讲username这个属性名字改成uname,密码也是同理
                .passwordParameter("passwd") //所以接口就应该这样写  http://localhost:8080/doLogin?uname=ppf&passwd=123  一般来说这个没有必要配置
                //successHandler 表示前后端分离的项目,登录成功后,需要跳转的页面,这时候,后端只要返回json给前端(登录成功的一个处理器)
                .successHandler(new AuthenticationSuccessHandler() {
                    @Override            //参数 authentication   是保存了登录成功的用户信息
                    public void onAuthenticationSuccess(HttpServletRequest req, HttpServletResponse resp, Authentication authentication) throws IOException, ServletException {
                        resp.setContentType("application/json;chartset=utf-8");  //设置要返回的json格式
                        PrintWriter out = resp.getWriter();
                        Map<String, Object> map = new HashMap<>();
                        map.put("status",200);
                        map.put("msg",authentication.getPrincipal()); //authentication.getPrincipal()  就是登录成功的用户信息
                        out.write(new ObjectMapper().writeValueAsString(map)); //这是写出去的 转成json串
                        out.flush();
                        out.close();
                    }
                })
                //这个是登录失败的一个处理器,与上面类似。比如登录失败,服务端要跳到哪个页面去
                .failureHandler(new AuthenticationFailureHandler() {
                    @Override   //这边只有异常,异常可以锁定出错的问题
                    public void onAuthenticationFailure(HttpServletRequest req, HttpServletResponse resp, AuthenticationException e) throws IOException, ServletException {
                        resp.setContentType("application/json;chartset=utf-8");  //设置要返回的json格式
                        PrintWriter out = resp.getWriter();
                        Map<String, Object> map = new HashMap<>();
                        map.put("status",401);
                        if(e instanceof LockedException){ //nstanceof 运算符是用来在运行时指出对象是否是特定类的一个实例
                            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","登录失败!");
                        }
                        out.write(new ObjectMapper().writeValueAsString(map)); //这是写出去的 转成json串
                        out.flush();
                        out.close();
                    }
                })
                .permitAll()  //这个表示和登录相关的接口 直接就可以访问。   permit 英文是 许可的意思
                .and()
                //这边配置注销登录配置
                .logout()
                .logoutUrl("/logout") //这是注销登录的url
                //这是注销登录成功的一个处理方法,返回前台json数据
                .logoutSuccessHandler(new LogoutSuccessHandler() {
                    @Override
                    public void onLogoutSuccess(HttpServletRequest req, HttpServletResponse resp, Authentication authentication) throws IOException, ServletException {
                        resp.setContentType("application/json;chartset=utf-8");  //设置要返回的json格式
                        PrintWriter out = resp.getWriter();
                        Map<String, Object> map = new HashMap<>();
                        map.put("status",200);
                        map.put("msg","注销登录成功"); //authentication.getPrincipal()  就是登录成功的用户信息
                        out.write(new ObjectMapper().writeValueAsString(map)); //这是写出去的 转成json串
                        out.flush();
                        out.close();
                    }
                })
                .and()
                .csrf().disable(); //这边表示  关闭 csrf攻击(跨站请求伪造)  为了防止测试时报错

    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值