package com.example.demo.config;
import com.example.demo.Service.UserDetailsServiceImpl;
import com.example.demo.filter.JwtAuthencationTokenFilter;
import com.example.demo.pojo.ResponseResult;
import com.example.demo.pojo.ResponseStatusCode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
public JwtAuthencationTokenFilter jwtAuthencationTokenFilter(){
return new JwtAuthencationTokenFilter();
}
@Autowired
private BCryptPasswordEncoder encoder;
@Autowired
private UserDetailsServiceImpl userDetailsService;
/**************************************************************
一,验证
**************************************************************/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(encoder);
}
/**************************************************************
二,授权
**************************************************************/
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authenticationProvider(authenticationProvider())
.httpBasic()
//未登录时 , 自定义响应结果
.authenticationEntryPoint((request, response, ex) -> {
customResponse(response, ResponseStatusCode.NO_Login,null);
});
http.authorizeRequests()
.antMatchers("/common").hasRole("common")
.antMatchers("/vip").hasRole("vip")
.antMatchers("/").authenticated();
//将jwt登录授权的拦截器 => 添加到用户验证之前
http.addFilterBefore(jwtAuthencationTokenFilter(), UsernamePasswordAuthenticationFilter.class);
/*
添加自定义 未授权和未授权的结果返回
*/
http.exceptionHandling()
.accessDeniedHandler((request, response, ex) -> {
customResponse(response, ResponseStatusCode.NO_AUTHORITY,null);
})
.authenticationEntryPoint((request, response, ex) -> {
customResponse(response, ResponseStatusCode.NO_Login,null);
});
//基于token,所有不需要csrf
http.csrf().disable();
// 基于token,所以不需要session
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
// 缓存管理,暂时用不到
http.headers().cacheControl();
}
@Bean
public AuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
//对默认的UserDetailsService进行覆盖
authenticationProvider.setUserDetailsService(userDetailsService);
authenticationProvider.setPasswordEncoder(encoder);
return authenticationProvider;
}
@Autowired
private ObjectMapper objectMapper;
// 自定义返回结果
private void customResponse(HttpServletResponse response, ResponseStatusCode code,Object data) throws IOException {
response.setContentType("application/json;charset=utf-8");
response.setStatus(code.getCode());
PrintWriter out = response.getWriter();
out.write(objectMapper.writeValueAsString(new ResponseResult<>(code, data)));
out.flush();
out.close();
}
}