• Spring Security 入门


    什么是Spring Security?

          Spring Security是一个能够为基于Spring的企业应用系统提供描述性安全访问控制解决方案的安全框架。它提供了一组可以在Spring应用上下文中配置的Bean,充分利用了Spring IoC(依赖注入,也称控制反转)和AOP(面向切面编程)功能,为应用系统提供声明式的安全访问控制功能,减少了为企业系统安全控制编写大量重复代码的工作。

    Spring Security的使用

    1.基于Spring boot创建Spring Security 项目

    2.填写项目信息

     3.选择webSpring Security

     

    4.写一个controller测试

    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    public class TestController {
    
        @RequestMapping("test")
        public String index() {
            return "Hello Word";
        }
    }

    5.启动项目

    输入localhost:8080会进入页面

    默认情况下,登录的用户名是 user,密码则是项目启动时随机生成的字符串,可以从启动的控制台日志中看到默认密码:

    这个随机生成的密码,每次启动时都会变。对登录的用户名/密码进行配置,有三种不同的方式:

    • application.properties 中进行配置
    • 通过 Java 代码配置在内存中
    • 通过 Java 从数据库中加载

    6.登录成功测试

    这里是正确的,不是出错

    输入test,可以看到测试时正确的

    用户名和密码配置

    1.配置文件配置用户名/密码

    在application.properties 文件中配置

    spring.security.user.name=lmc
    spring.security.user.password=123

    2.Java 配置用户名/密码

    自己写一个config类

    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
    import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
    import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
    import org.springframework.security.crypto.password.PasswordEncoder;
    
    @Configuration
    public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
            //下面这两行配置表示在内存中配置了两个用户
            auth.inMemoryAuthentication()
                    .withUser("lmc").roles("admin").password("123")
                    .and()
                    .withUser("lingmeng").roles("user").password("123");
        }
        @Bean
        PasswordEncoder passwordEncoder() {
            return new BCryptPasswordEncoder();
        }
    }

    登录配置

    对于登录接口,登录成功后的响应,登录失败后的响应,我们都可以在 WebSecurityConfigurerAdapter 的实现类中进行配置

    @Configuration
    public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
        @Autowired
        VerifyCodeFilter verifyCodeFilter;
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.addFilterBefore(verifyCodeFilter, UsernamePasswordAuthenticationFilter.class);
            http
            .authorizeRequests()//开启登录配置
            .antMatchers("/test").hasRole("admin")//表示访问 /hello 这个接口,需要具备 admin 这个角色
            .anyRequest().authenticated()//表示剩余的其他接口,登录之后就能访问
            .and()
            .formLogin()
            //定义登录页面,未登录时,访问一个需要登录之后才能访问的接口,会自动跳转到该页面
            .loginPage("/login_p")
            //登录处理接口
            .loginProcessingUrl("/doLogin")
            //定义登录时,用户名的 key,默认为 username
            .usernameParameter("uname")
            //定义登录时,用户密码的 key,默认为 password
            .passwordParameter("passwd")
            //登录成功的处理器
            .successHandler(new AuthenticationSuccessHandler() {
                @Override
                public void onAuthenticationSuccess(HttpServletRequest req, HttpServletResponse resp, Authentication authentication) throws IOException, ServletException {
                        resp.setContentType("application/json;charset=utf-8");
                        PrintWriter out = resp.getWriter();
                        out.write("success");
                        out.flush();
                    }
                })
                .failureHandler(new AuthenticationFailureHandler() {
                    @Override
                    public void onAuthenticationFailure(HttpServletRequest req, HttpServletResponse resp, AuthenticationException exception) throws IOException, ServletException {
                        resp.setContentType("application/json;charset=utf-8");
                        PrintWriter out = resp.getWriter();
                        out.write("fail");
                        out.flush();
                    }
                })
                .permitAll()//和表单登录相关的接口统统都直接通过
                .and()
                .logout()
                .logoutUrl("/logout")
                .logoutSuccessHandler(new LogoutSuccessHandler() {
                    @Override
                    public void onLogoutSuccess(HttpServletRequest req, HttpServletResponse resp, Authentication authentication) throws IOException, ServletException {
                        resp.setContentType("application/json;charset=utf-8");
                        PrintWriter out = resp.getWriter();
                        out.write("logout success");
                        out.flush();
                    }
                })
                .permitAll()
                .and()
                .httpBasic()
                .and()
                .csrf().disable();
        }
    }

    忽略拦截

    如果某一个请求地址不需要拦截的话,有两种方式实现:

    • 设置该地址匿名访问
    • 直接过滤掉该地址,即该地址不走 Spring Security 过滤器链

        推荐使用第二种方案:

    @Configuration
    public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
        @Override
        public void configure(WebSecurity web) throws Exception {
            web.ignoring().antMatchers("/vercode");
        }
    }
  • 相关阅读:
    edgecore
    十问 Linux 虚拟内存管理 (glibc)
    Covered Path
    Journey Planning
    K for the Price of One
    Candies!
    2种方式解决nginx负载下的Web API站点里swagger无法使用
    分布式环境下的数据一致性问题的方案讨论
    static,你还敢用吗?
    分离EF connectionString里的db连接串
  • 原文地址:https://www.cnblogs.com/limengcheng/p/12243865.html
Copyright © 2020-2023  润新知