Spring Security 配置类

package cn.tedu.csmall.product.config;

import cn.tedu.csmall.product.filter.JwtAuthorizationFilter;
import cn.tedu.csmall.commons.web.JsonResult;
import cn.tedu.csmall.commons.web.ServiceCode;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

@Slf4j
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true) // 开启全局的基于方法的安全检查, 即: 在方法上添加注解来检查权限
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Autowired
    private JwtAuthorizationFilter jwtAuthorizationFilter;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // 开启Spring Security自带的CorsFilter, 已解决跨域问题
        //对于复杂请求,浏览器会先对服务器端发送OPTIONS类型的请求,以执行预检(PreFlight),如果预检通过,才会执行本应该发送的请求。
        http.cors();

        // 配置Spring Security框架使用(创建) Session的策略
        // (确保不携带JWT, SpringSecurity不能基于Session找到SecurityContext并读取到认证信息)
        // STATELESS: 无状态的, 完全不使用Session
        // NEVER: 从不主动创建session, 但是,当Session已经被创建后, 仍会正常使用
        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);

        // 将JWT过滤器添加到Spring Security框架的某些过滤器之前
        // 能在路过滤器前执行的只有过滤器
        http.addFilterBefore(jwtAuthorizationFilter, UsernamePasswordAuthenticationFilter.class);

        //处理未通过认证时访问受保护的资源时被拒绝访问
        http.exceptionHandling().authenticationEntryPoint(new AuthenticationEntryPoint() {
            @Override
            public void commence(HttpServletRequest request, HttpServletResponse response,
                                 AuthenticationException e) throws IOException, ServletException {
                String message = "您当前未登录, 请先登录!";
                log.warn(message);

                JsonResult jsonResult = JsonResult.fail(ServiceCode.ERR_UNAUTHORIZED, message);
                String jsonString = JSON.toJSONString(jsonResult);

                response.setContentType("application/json;charset=utf-8");
                PrintWriter printWriter = response.getWriter();
                printWriter.println(jsonString);
                printWriter.close();
            }
        });


        // 禁用"防止伪造的跨域攻击的防御机制"
        http.csrf().disable();


        // 白名单
         /*
         使用1个星号,可以通配此层级的任何资源,
            例如:/admin/*,可以匹配:/admin/add-new、/admin/list,但不可以匹配:/admin/password/change
         使用2个连续的星可以,可以通配若干层级的资源,
            例如:/admin/**,可以匹配:/admin/add-new、/admin/password/change
          */
        String[] urls = {
                "/doc.html",
                "/**/*.css",
                "/**/*.js",
                "/swagger-resources",
                "/v2/api-docs"
        };

        // 配置授权访问
        // 注意:以下授权访问的配置,是遵循“第一匹配原则”的,即“以最先匹配到的规则为准”
        // 例如:anyRequest()是匹配任何请求,通常,应该配置在最后,表示“除了以上配置过的以外的所有请求”
        // 所以,在开发实践中,应该将更具体的请求配置在靠前的位置,将更笼统的请求配置在靠后的位置
        http.authorizeRequests()   // 开始对请求进行授权
                /*.mvcMatchers(HttpMethod.OPTIONS,"/**")
                .permitAll()
                // 以上两句将所有OPTIONS类型的请求全部直接许可*/
                .mvcMatchers(urls) // 匹配某些请求
                .permitAll()       // 许可, 即不需要通过认证就可以访问
                .anyRequest()      // 任何请求, 通常在最后配置
                .authenticated();  // 要求已经完成认真的

        // 如果调用以下方法, 当Security认为需要通过认证, 但实际未通过认证时, 就会跳转到登录页面
        // 如果为调用以下方法, 将会响应403错误
        // http.formLogin();

        // Spring Security框架的典型特征  都是默认调用了父类的方法
        // super.configure(http);  不要保留调用父级同名方法的代码
    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值