欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

springboot前后端分离实现spring security

程序员文章站 2022-03-15 11:42:29
...

1、引入spring security依赖

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

2、定义与前端交互返回的数据类

@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class ResultResponse implements java.io.Serializable {
    private int code;
    private String message;
    private Object data;
}

3、自定义security安全拦截状态以JSON格式返回前端

这是我的目录结构
springboot前后端分离实现spring security
登录成功

@Component
public class LoginSuccessHandler implements AuthenticationSuccessHandler {
    @Autowired
    RedisUtil redisUtil;
    @Override
    public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
        String token = redisUtil.get("token");
        ResultResponse resultResponse = new ResultResponse(Constans.STATUS_OK,Constans.MESSAGE_OK,new Token(token));
        httpServletResponse.setCharacterEncoding("UTF-8");
        httpServletResponse.getWriter().write(JSON.toJSONString(resultResponse));
    }
}

登录失败

@Component
public class LoginFailHandler implements AuthenticationFailureHandler {
    @Override
    public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
        ResultResponse resultResponse = new ResultResponse(Constans.STATUS_FAIL,Constans.MESSAGE_FAIL+"登录失败",null);
        httpServletResponse.setCharacterEncoding("UTF-8");
        httpServletResponse.getWriter().write(JSON.toJSONString(resultResponse));
    }
}

无权访问

@Component
public class NoRightAccessHandler implements AccessDeniedHandler {
    @Override
    public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AccessDeniedException e) throws IOException, ServletException {
        ResultResponse resultResponse = new ResultResponse(Constans.STATUS_FAIL,Constans.MESSAGE_FAIL+"您无权访问",null);
        httpServletResponse.setCharacterEncoding("UTF-8");
        httpServletResponse.getWriter().write(JSON.toJSONString(resultResponse));
    }
}

未登录

@Component
public class NotLoginEntryPoint implements AuthenticationEntryPoint {
    @Override
    public void commence(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
        ResultResponse resultResponse = new ResultResponse(Constans.STATUS_FAIL,Constans.MESSAGE_FAIL+"无访问权限,请先登录",null);
        httpServletResponse.setCharacterEncoding("UTF-8");
        httpServletResponse.getWriter().write(JSON.toJSONString(resultResponse));
    }
}

注销成功

@Component
public class ReqLogoutSuccessHandler implements LogoutSuccessHandler {
    @Override
    public void onLogoutSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
        ResultResponse resultResponse = new ResultResponse(Constans.STATUS_FAIL,Constans.MESSAGE_FAIL+"注销成功",null);
        httpServletResponse.setCharacterEncoding("UTF-8");
        httpServletResponse.getWriter().write(JSON.toJSONString(resultResponse));
    }
}

3、配置登录拦截全局配置类securityConfig

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    //注入未登录返回状态类
    @Autowired
    NotLoginEntryPoint notLoginEntryPoint;
    //注入登录成功返回状态类
    @Autowired
    LoginSuccessHandler loginSuccessHandler;
    //注入登录失败返回状态类
    @Autowired
    LoginFailHandler loginFailHandler;
    //注入退出返回状态类
    @Autowired
    ReqLogoutSuccessHandler reqLogoutSuccessHandler;
    //注入无权访问返回状态类
    @Autowired
    NoRightAccessHandler noRightAccessHandler;
    //密码编码器,使用BCrypt加密算法加密
    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }

    //安全拦截机制
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()  //屏蔽csrf控制,csrf为跨站请求伪造
                .httpBasic().authenticationEntryPoint(notLoginEntryPoint)
                .and()
                .authorizeRequests()
                .antMatchers("/**/**").anonymous() //允许不需要授权就可以访问
                .anyRequest()
                .authenticated()// 其他 url 需要身份认证
                .and()
                .formLogin()  //开启登录
                .loginProcessingUrl("/user/login")//登录处理地址
                .usernameParameter("userId")//定义登录时,用户名的参数名,默认为 username
                .passwordParameter("password")//定义登录时,密码的参数名,默认为 password
                .successHandler(loginSuccessHandler) // 登录成功
                .failureHandler(loginFailHandler) // 登录失败
                .and()
                .logout()
                .logoutSuccessHandler(reqLogoutSuccessHandler)  //注销成功
                .permitAll()
                .and()
                .cors();//允许跨域,如果springboot/springmvc已有跨域配置,自动采用springboot/springmvc跨域配置
        http.exceptionHandling().accessDeniedHandler(noRightAccessHandler); // 无权访问 JSON 格式的数据

    }
}