前后端分离项目中SpringSecurity配置详解

Spring Security默认在登录或者注销之后返回的响应不是JSON格式的数据,并不适用于前后端分离式项目。但是Spring Security提供了大量的配置项,通过这些配置项,我们就可以把它配置成我们需要的样子。

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
//开启权限注解,在Controller类的方法上使用@PreAuthorize("hasRole('admin')")进行权限控制
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    private final UserService userService;
    private final ObjectMapper objectMapper;

    public WebSecurityConfig(UserService userService, ObjectMapper objectMapper) {
        this.userService = userService;
        this.objectMapper = objectMapper;
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.formLogin()
                 //配置处理登录表单的URL,与表单action一致即可
                .loginProcessingUrl("/api/login")
                 //处理登录成功
                .successHandler((request, response, authentication) -> {
                    response.setContentType("application/json;charset=utf-8");
                    PrintWriter out = response.getWriter();
                    out.write(objectMapper.writeValueAsString(Response.success("登录成功!")));
                    out.flush();
                    out.close();
                })
                 //处理登录失败
                .failureHandler((request, response, exception) -> {
                    response.setContentType("application/json;charset=utf-8");
                    PrintWriter out = response.getWriter();
                    out.write(objectMapper.writeValueAsString(Response.error("账号或密码错误!")));
                    out.flush();
                    out.close();
                })
                 //处理未登录时的行为,默认为跳转到/login
                .and().exceptionHandling()
                .authenticationEntryPoint((request, response, authException) -> {
                    response.setContentType("application/json;charset=utf-8");
                    response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
                    PrintWriter out = response.getWriter();
                    out.write(objectMapper.writeValueAsString(Response.error("授权已过期,请重新登录!")));
                    out.flush();
                    out.close();
                })
                 //处理已登录但权限不足
                .accessDeniedHandler((request, response, exception) -> {
                    response.setContentType("application/json;charset=utf-8");
                    response.setStatus(HttpServletResponse.SC_FORBIDDEN);
                    PrintWriter out = response.getWriter();
                    out.write(objectMapper.writeValueAsString(Response.error("您没有权限进行此操作!")));
                    out.flush();
                    out.close();
                })
                .and().logout()
                 //配置注销的URL,请求方式为GET
                .logoutUrl("/api/logout")
                 //处理注销成功
                .logoutSuccessHandler((request, response, authentication) -> {
                    response.setContentType("application/json;charset=utf-8");
                    PrintWriter out = response.getWriter();
                    out.write(objectMapper.writeValueAsString(Response.success("注销成功!")));
                    out.flush();
                    out.close();
                })
                .and().csrf().disable();
    }
}
共 0 条评论