Spring Security(一)

开始

1,只要导入maven坐标就自动起效
2,他会自动的保护你所有的接口
3,登录账户(user)密码(后台生成的那一串东西)
在这里插入图片描述

一,自定义登录密码(认证)

第一种方式 : yml

spring:
  security:
    user:
      name: jies
      password: 123456

第二种方式:config

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())//BCryptPasswordEncoder--密码加密
                .withUser("jies").password(new BCryptPasswordEncoder().encode("123456")).roles("admin")
                .and()
                .withUser("jies2").password(new BCryptPasswordEncoder().encode("123456")).roles("user");
    }
}

还可以

    //设置加密格式
    @Bean
    PasswordEncoder passwordEncoder() {
//        return NoOpPasswordEncoder.getInstance();
        return new BCryptPasswordEncoder();
    }
    
    //存在内存中
    @Bean
    @Override
    protected UserDetailsService userDetailsService() {
        InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
        manager.createUser(User.withUsername("jies").password(new BCryptPasswordEncoder().encode("123456")).roles("admin").build());
        manager.createUser(User.withUsername("jies2").password(new BCryptPasswordEncoder().encode("123456")).roles("user").build());
        return manager;
    }

二,自定义登录页

还是在SecurityConfig 中配置,注意:不同参数的 configure方法的作用

  • 自定义登录
  • 失败或成功的跳转
  • 注销
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    //
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
                .withUser("jies").password(new BCryptPasswordEncoder().encode("123456")).roles("admin")
                .and()
                .withUser("jies2").password(new BCryptPasswordEncoder().encode("12345")).roles("admin");
    }

    //web资源
    @Override
    public void configure(WebSecurity web) throws Exception {
        //忽略路径
        web.ignoring().antMatchers("/js/**", "/css/**", "/images/**");
    }

    //自定义登录界面
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //开启配置
        http.authorizeRequests()
                //所有请求都要认证才能访问
                .anyRequest().authenticated()
                .and()
                //表单配置
                .formLogin()
                //登录页面 默认情况下  登录接口和登录页面一样
                .loginPage("/login.html")
                //配置登录接口
                .loginProcessingUrl("/login.html")
                //定制login.html的参数名
                .usernameParameter("username")
                .passwordParameter("password")
                //登录成功时跳转
                //无论从哪里来都跳转到success --请求转发
//                .successForwardUrl("/success")
                //默认跳转 第二个参数默认为false--重定向 如果为true时跟successForwardUrl效果一样
                .defaultSuccessUrl("/success")
                //失败时跳转
                //请求转发
                .failureForwardUrl("/failure")
                //重定向跳转
//                .failureUrl("/failure")
                //只放行login,
                .permitAll()
                //注销
                .and()
                //注销
                .logout()
                //更改注销的请求方式
                .logoutRequestMatcher(new AntPathRequestMatcher("/logout","POST"))
                //注销成功跳转到那个页面
                .logoutSuccessUrl("/login.html")
                //清除session,默认为true
                .invalidateHttpSession(true)
                //清除认证信息,默认为true
                .clearAuthentication(true)
                .and()
                .csrf().disable();

    }
}
  • login.html的method是post,还要有submit

三,前后端分离 JSON交互

首先:

  • 有状态登录

典型的设计如 Tomcat 中的 Session。

对外提供的都使用 RESTful 风格的接口

  • 服务端不保存任何客户端请求者信息
  • 客户端的每次请求必须具备自描述信息,通过这些信息识别客户端身份

简单来说就是完成相应的操作后给前端一个响应

登录成功的回调

       //登录成功的回调
       //successHandler 的功能十分强大,甚至已经囊括了 defaultSuccessUrl 和 successForwardUrl 的功能
       .successHandler(new AuthenticationSuccessHandler() {
           @Override
           public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
               response.setContentType("application/json;charset=utf-8");
               PrintWriter writer = response.getWriter();
               writer.write(new ObjectMapper().writeValueAsString(authentication));
               writer.flush();
               writer.close();
           }
       })

登录失败的回调

       //登录失败的回调
       .failureHandler(new AuthenticationFailureHandler() {
           @Override
           public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) throws IOException, ServletException {
               response.setContentType("application/json;charset=utf-8");
               PrintWriter writer = response.getWriter();
               writer.write(new ObjectMapper().writeValueAsString(e.getMessage()));
               writer.flush();
               writer.close();
           }
       })

注销成功的回调

       //注销成功的回调
       .logoutSuccessHandler(new LogoutSuccessHandler() {
           @Override
           public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
               response.setContentType("application/json;charset=utf-8");
               PrintWriter writer = response.getWriter();
               writer.write(new ObjectMapper().writeValueAsString("注销成功"));
               writer.flush();
               writer.close();
           }
       })

没有认证时回调

        //没有认证时回调
        .exceptionHandling()
        .authenticationEntryPoint(new AuthenticationEntryPoint() {
            @Override
            public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) throws IOException, ServletException {
                response.setContentType("application/json;charset=utf-8");
                PrintWriter writer = response.getWriter();
                writer.write(new ObjectMapper().writeValueAsString("用户还没登录!"));
                writer.flush();
                writer.close();
            }
        })

四,授权

权限

  • 该方式上级不具备下级的权限,
    //自定义登录界面
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //开启配置
        http.authorizeRequests()
                //授权,注意顺序
                .antMatchers("/admin/**").hasRole("admin")
                .antMatchers("/user/**").hasRole("user")
                //所有请求都要认证才能访问
                .anyRequest().authenticated()

角色继承

  • 如果需要角色继承,要在配置类中添加
    //角色继承
    @Bean
    RoleHierarchy roleHierarchy() {
        RoleHierarchyImpl hierarchy = new RoleHierarchyImpl();
        hierarchy.setHierarchy("ROLE_admin > ROLE_user");
        return hierarchy;
    }

更换数据来源

  • 用户数据存入数据库
    前面的认证第三种方式UserDetailsService有两个实现类
    在这里插入图片描述

  • 接下来看一下存数据进数据库的那个
    在这里插入图片描述

  • 需要将里面的SQL改一下

  • 代码如下

    @Autowired
    DataSource dataSource;

    @Bean
    @Override
    protected UserDetailsService userDetailsService() {
        JdbcUserDetailsManager manager = new JdbcUserDetailsManager(dataSource);
        if(!manager.userExists("jies")){
            manager.createUser(User.withUsername("jies").password(new BCryptPasswordEncoder().encode("123456")).roles("admin").build());
        }
        if (!manager.userExists("jies2")){
            manager.createUser(User.withUsername("jies2").password(new BCryptPasswordEncoder().encode("123456")).roles("user").build());
        }
        return manager;
    }

数据库成功插入数据
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值