网站首页 > 文章精选 正文
前言
1、此文适合刚刚开始学习的同学,欢迎指正.
2、刚刚开始学习spring security整合JWT时总是无法分清楚JWT整合的具体过程,在网上找到的代码总是没有详细的注释,所以写了这样一篇文章,来记录。
备注:此文书写结构为先贴图或者代码,然后分析代码和内容,所以建议代码和下面分析的文字对比阅读
一、文件结构
整合JWT一共会使用
6个配置文件+各自的用户和权限文件(这里使用了5个表)
以上是会用到的文件除单文件外均使用红色框选出来,可以同下述文章对比查看
二、代码解析
1.securityConfig文件内容及分析
代码如下(示例):
/**
* SpringSecurity的配置
*/
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UmsAdminService adminService;
@Autowired
private RestfulAccessDeniedHandler restfulAccessDeniedHandler;
@Autowired
private RestAuthenticationEntryPoint restAuthenticationEntryPoint;
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.csrf()// 由于使用的是JWT,我们这里不需要csrf
.disable()
.sessionManagement()// 基于token,所以不需要session
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers(HttpMethod.GET, // 允许对于网站静态资源的无授权访问
"/",
"/*.html",
"/favicon.ico",
"/**/*.html",
"/**/*.css",
"/**/*.js",
"/swagger-resources/**",
"/v2/api-docs/**"
)
.permitAll()
.antMatchers("/admin/login", "/admin/register")// 对登录注册要允许匿名访问
.permitAll()
.antMatchers(HttpMethod.OPTIONS)//跨域请求会先进行一次options请求
.permitAll()
.antMatchers("/**")//测试时全部运行访问
.permitAll()
.anyRequest()// 除上面外的所有请求全部需要鉴权认证
.authenticated();
// 禁用缓存
httpSecurity.headers().cacheControl();
// 添加JWT filter
httpSecurity.addFilterBefore(jwtAuthenticationTokenFilter(), UsernamePasswordAuthenticationFilter.class);
//添加自定义未授权和未登录结果返回
httpSecurity.exceptionHandling()
.accessDeniedHandler(restfulAccessDeniedHandler)
.authenticationEntryPoint(restAuthenticationEntryPoint);
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//使用自定义省份验证组件
auth.userDetailsService(userDetailsService())
.passwordEncoder(passwordEncoder());
}
@Bean
public PasswordEncoder passwordEncoder() {
return new MyPasswordEncoder();
}
//获取用户信息
@Override
@Bean
public UserDetailsService userDetailsService() {
//获取登录用户信息
return new UserDetailsService() {
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
UmsMember adminByName = adminService.getAdminByName(username);
if(adminByName!=null){
//查询用户的权限
List<UmsPermission> permissionList = adminService.getPermissionList(adminByName.getId());
return new MemberDetails(adminByName, permissionList);
}
throw new UsernameNotFoundException("用户名或密码错误");
}
};
}
@Bean
public JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter() {
return new JwtAuthenticationTokenFilter();
}
/**
* 允许跨域调用的过滤器
*/
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.addAllowedOrigin("*");
config.setAllowCredentials(true);
config.addAllowedHeader("*");
config.addAllowedMethod("*");
source.registerCorsConfiguration("/**", config);
FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
bean.setOrder(0);
return new CorsFilter(source);
}
//将Spring Security自带的authenticationManager声明成Bean
//声明它的作用是用它帮我们进行认证操作,调用这个Bean的authenticate方法会由Spring Security自动帮我们做认证。
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}
1.1 代码分析
security配置文件中一共使用了7个方法:
方法一:configure(HttpSecurity httpSecurity)
1、此方法中主要定义了JWT过滤器
httpSecurity.addFilterBefore(jwtAuthenticationTokenFilter(), UsernamePasswordAuthenticationFilter.class);
这一句话将JWT的过滤类添加到了security的过滤规则UsernamePasswordAuthenticationFilter之后;
采用的是addFilterBefore这个方法,这个方法和addFilter以及addFilterAfter类似;分别是将自定义的过滤器添加在某个过滤器之前/之后/相等的位置;
上图中绿色部分就是spring security自带的过滤器,而使用addFilter等方法就是将我们自定义的过滤器加入自带过滤器的队列中;
而本身的UsernamePasswordAuthenticationFilter和BasicAuthenticationFilter是需要手动开启的,而在这里我们没有使用,所以使用addFilter添加在哪个位置不影响。
###### 2、加入自定义返回类
httpSecurity.exceptionHandling()
.accessDeniedHandler(restfulAccessDeniedHandler)
.authenticationEntryPoint(restAuthenticationEntryPoint);
返回类内容:
/**
* 当未登录或者token失效访问接口时,自定义的返回结果
* https://gitee.com/zscat-platform/mall on 2018/5/14.
*/
@Component
public class RestAuthenticationEntryPoint implements AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json");
response.getWriter().println(JsonUtil.objectToJson(自己封装的统一返回类(authException.getMessage())));
response.getWriter().flush();
}
}
/**
* 当访问接口没有权限时,自定义的返回结果
*/
@Component
public class RestfulAccessDeniedHandler implements AccessDeniedHandler {
@Override
public void handle(HttpServletRequest request,
HttpServletResponse response,
AccessDeniedException e) throws IOException, ServletException {
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json");
response.getWriter().println(JsonUtil.objectToJson(自己封装的统一返回类(e.getMessage())));
response.getWriter().flush();
}
}
方法二、configure(AuthenticationManagerBuilder auth)
1、此方法中主要配置自定义的加密类
//使用自定义身份验证组件
auth.userDetailsService(userDetailsService())
.passwordEncoder(passwordEncoder());
在springboot 2.x之前好像是可以使用自带的加密方式,springbbot2.x之后好像就必须自定义加密方式了,具体还没有了解到,欢迎补充。
其中passwordEncoder调用的方法三
方法三:自定义加密类
1、此方法中导入自定义的加密类
@Bean
public PasswordEncoder passwordEncoder() {
return new MyPasswordEncoder();
}
使用方式由方法二中调用
方法四:userDetailsService()
此类用于获取用户信息和比对用户数据
return new UserDetailsService() {
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
UmsMember adminByName = adminService.getAdminByName(username);
if(adminByName!=null){
//查询用户的权限
List<UmsPermission> permissionList = adminService.getPermissionList(adminByName.getId());
return new MemberDetails(adminByName, permissionList);
}
throw new UsernameNotFoundException("用户名或密码错误");
}
};
此类方法有些喜欢单独定义一个类来使用,这里是写在一起,单独定义原理一样,只不过就是在return的时候调用一个继承了UserDetailsService的类
方法五:jwtAuthenticationTokenFilter()
1、此方法中主要导入JWT工具类
@Bean
public JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter() {
return new JwtAuthenticationTokenFilter();
}
此方法中new了一个写好的JWT过滤类方法,在**方法1**中添加JWT过滤时引入
总结
本文章分为3个模块,这是第一个模块主要分析securityconfig部分
Lintge-一天一个好玩的知识
猜你喜欢
- 2024-12-30 简单的使用SpringBoot整合SpringSecurity
- 2024-12-30 Spring Security 整合OAuth2 springsecurity整合oauth2+jwt+vue
- 2024-12-30 DeepSeek-Coder-V2震撼发布,尝鲜体验
- 2024-12-30 一个数组一行代码,Spring Security就接管了Swagger认证授权
- 2024-12-30 简单漂亮的(图床工具)开源图片上传工具——PicGo
- 2024-12-30 Spring Boot(十一):Spring Security 实现权限控制
- 2024-12-30 绝了!万字搞定 Spring Security,写得太好了
- 2024-12-30 SpringBoot集成Spring Security springboot集成springsecurity
- 2024-12-30 SpringSecurity密码加密方式简介 spring 密码加密
- 2024-12-30 Spring cloud Alibaba 从入门到放弃
- 最近发表
- 标签列表
-
- newcoder (56)
- 字符串的长度是指 (45)
- drawcontours()参数说明 (60)
- unsignedshortint (59)
- postman并发请求 (47)
- python列表删除 (50)
- 左程云什么水平 (56)
- 计算机网络的拓扑结构是指() (45)
- 稳压管的稳压区是工作在什么区 (45)
- 编程题 (64)
- postgresql默认端口 (66)
- 数据库的概念模型独立于 (48)
- 产生系统死锁的原因可能是由于 (51)
- 数据库中只存放视图的 (62)
- 在vi中退出不保存的命令是 (53)
- 哪个命令可以将普通用户转换成超级用户 (49)
- noscript标签的作用 (48)
- 联合利华网申 (49)
- swagger和postman (46)
- 结构化程序设计主要强调 (53)
- 172.1 (57)
- apipostwebsocket (47)
- 唯品会后台 (61)
- 简历助手 (56)
- offshow (61)