SpringBoot+Spring Security安全框架整合与初探

SpringBoot+Spring Security安全框架整合与初探

市面上存在比较有名的安全框架:Shiro,Spring Security !

Spring Security官网介绍
Spring Security is a powerful and highly customizable authentication and access-control framework. It is the de-facto standard for securing Spring-based applications.

Spring Security is a framework that focuses on providing both authentication and authorization to Java applications. Like all Spring projects, the real power of Spring Security is found in how easily it can be extended to meet custom requirements


中文翻译:Spring Security是一个功能强大且高度可定制的身份验证和访问控制框架。它是保护基于Spring的应用程序的事实标准。
SpringSecurity是一个框架,它关注于为Java应用程序提供身份验证和授权。与所有Spring项目一样,Spring安全性的真正威力在于它可以多么容易地扩展以满足定制需求

Spring Security主要做认证和授权


  • WebSecurityConfigurerAdapter:自定义Security策略
  • AuthenticationManagerBuilder:自定义认证策略
  • @EnableWebSecurity:开启WebSecurity模式

认证

身份验证是关于验证您的凭据,如用户名/用户ID和密码,以验证您的身份。

身份验证通常通过用户名和密码完成,有时与身份验证因素结合使用。

授权

身份验证是关于验证您的凭据,如用户名/用户ID和密码,以验证您的身份。

身份验证通常通过用户名和密码完成,有时与身份验证因素结合使用。


Spring Security入门

引入Spring Security 模块

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

创建配置文件SecurityConfig

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

}

重写身份管理configure(AuthenticationManagerBuilder auth)

在重写的身份验证中编写内存中添加的用户

    @Override
    //身份管理
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
                //使用自定义密码验证策略
             .passwordEncoder(new MyPasswordEncoder())
             .withUser("bc").roles("admin").password("$2a$10$KzeGSl1f7cQPgK6fWnUmie6B9twiehYvvXDtQ1Gi0WCLa.rt28j2i")
             .and()
             .withUser("admin").roles("admin").password("$2a$10$2UaOufuypWR1TASuso2S6.u6TGL7nuAGCsb4RZ5X2SMEuelwQBToO")
             .and()
             .withUser("user").roles("user").password("$2a$10$2UaOufuypWR1TASuso2S6.u6TGL7nuAGCsb4RZ5X2SMEuelwQBToO");
    }

//使用自定义密码验证策略
.passwordEncoder(new MyPasswordEncoder())

此处写了一个MyPasswordEncoder,使用BCrypt加密算法

public class MyPasswordEncoder implements PasswordEncoder {
    @Override
    //加密
    public String encode(CharSequence rawPassword) {
        String encode = new BCryptPasswordEncoder().encode(rawPassword);
        return encode;
    }

    @Override
    //解密
    public boolean matches(CharSequence rawPassword, String encodedPassword) {

        boolean checkpw = BCrypt.checkpw(rawPassword.toString(), encodedPassword);
        return checkpw;
    }

    public static void main(String[] args) {
        String bc = new MyPasswordEncoder().encode("bc");
        System.out.println(bc);
    }

重写登陆配置configure(HttpSecurity http)并添加配置

@Override
    //登陆配置
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests() //开启登录认证
                .antMatchers("/sctoken").hasRole("admin") //访问接口需要admin的角色
                .antMatchers("/login").permitAll()  //登陆接口开放
                .anyRequest().authenticated() // 其他所有的请求 只需要登录即可
                .and().formLogin()
                .loginPage("/index.html") //自定义的登录页面
                .loginProcessingUrl("/login") //登录处理接口
                .usernameParameter("username") //定义登录时的用户名的key 默认为username
                .passwordParameter("password") //定义登录时的密码key,默认是password
                .successHandler(new AuthenticationSuccessHandler() {    //成功登陆回调
                    @Override
                    public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
                        httpServletResponse.setContentType("application/json;charset=utf-8");
                        PrintWriter out = httpServletResponse.getWriter();
                        out.write("success");
                        out.flush();
                    }
                }) //登录失败回调
                .failureHandler(new AuthenticationFailureHandler() {
                    @Override
                    public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
                        httpServletResponse.setContentType("application/json;charset=utf-8");
                        PrintWriter out = httpServletResponse.getWriter();
                        out.write("fail");
                        out.flush();
                    }
                })
                .permitAll() //通过 不拦截,增加前面配的路径决定,这是指和登录表单相关的接口 都通过
                .and().logout() //退出登录配置
                .logoutUrl("/logout") //退出登录接口
                .logoutSuccessHandler(new LogoutSuccessHandler() {  //注销成功回调
                    @Override
                    public void onLogoutSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
                        httpServletResponse.setContentType("application/json;charset=utf-8");
                        PrintWriter out = httpServletResponse.getWriter();
                        out.write("logout success");
                        out.flush();
                    }
                }) //退出登录成功 处理器
                .permitAll() //退出登录的接口放行
                .and()
                .httpBasic()    //httpBasic认证
                .and()
                .csrf().disable(); //csrf关闭 如果自定义登录 需要关闭

    }

其中的自定义登录页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title><!DOCTYPE html>
        <html lang="en">
        <head>
        <meta charset="UTF-8">
        <title>自定义登录页面</title>
    <!-- 引入样式 -->
    <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
</head>
<body>
<div id="app">
    用户名: <el-input v-model="username" placeholder="请输入内容"></el-input>
    密码:  <el-input v-model="password" placeholder="请输入内容"></el-input>
    <el-button type="success" @click="login()">提交</el-button>
</div>
<!-- 引入组件库 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

<script>
    new Vue({
        el: "#app",
        data:{
            username:"",
            password:""
        },
        methods:{
            login(){
                axios.post("/login?username="+this.username+"&password="+this.password).then((res)=>{
                    if (res.data == "success"){
                        this.$message.success("登录成功");
                    }else{
                        this.$message.error("用户名或密码错误");
                    }
                })
            }
        }
    });
</script>
</body>
</html></title>
</head>
<body>

</body>
</html>

这时候去试着访问/sctoken接口会自动跳转到index.html要求登陆,登录成功后重新访问接口就能正常返回了

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值