社区微信群开通啦,扫一扫抢先加入社区官方微信群
社区微信群
如果你看到了该文章说明对spring框架有一定了解,相信你已经知道如何通过springboot进行项目构建
springboot想要支持安全验证以及web支持只需要在pom(如果是maven)文件中引入以下starter
//安全包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
//web包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-web'
http://localhost:8080
默认情况下控制台会输出一串密码串user
密码就是控制台中的密码串只需要在application.yml中配置即可
你是谁
干什么
的权限WebSecurityConfigurerAdapter
并且添加 @EnableWebSecurity
注解即可配置security
JwtSecurityConfig
继承 WebSecurityConfigurerAdapter
config
方法可能有些人要问为什么不是下图:
这是应为formLogin
是表单登录基于session-cookie
机制进行用户认证的,而前后端分离一般使用jwt
即用户状态保存在客户端中,
前后端交互通过api接口无session
生成,所以我们不需要配置formLogin
我们需要禁用session
我们再次访问 http://localhost:8080
发现没有登录页面,而是返回403页面,这是因为security 检测到项目中有WebSecurityConfigurerAdapter
的实现类并配置了config,所以它认为用户要自定义security所以默认的表单认证失效(除非你配置了formLogin) 至于403 是因为我们配置了所有路径都需要通过认证(包括/
路径)
返回403 正是我们想要的,说明了security起作用了,拦截保护了所有请求,同时还赋予我们自定义功能
/login
为匿名访问 防止被拦截无法进行登录AuthenticationManager
认证管理器,如果我们什么都不配置默认使用的是ProviderManager
是ioc运行时注册的bean 我们无法在编译时声明注入到controller,所以需要我们把默认的ProviderManager
在编译期声明为beanMyUserDetailsServiceImpl
实现 UserDetailsService
认证管理器在进行认证时会调用
loadUserByUsername
方法把客户端传递回来的用户名传给username
参数 我们根据该参数去我们存储用户信息的地方调用用户信息并填充UserDetails
对象返回即可,真正做密码匹配的是DaoAuthenticationProvider
它是认证管理器AuthenticationManager
的子类 ,默认情况我们无需配置该类。
/login
进行登录 (选中你们喜欢的客户端(postman
)进行测试)我使用apipost
我们发现并没有我们期待的事发生控制台并没有报错 抛出
UsernameNotFoundException
异常,并且客户端返回403异常,为什么会出现这种问题? 因为security在默认情况(用户未配置认证异常处理时候会默认返回403异常),那么我们怎么自定义呢?
MyAuthenticationEntryPoint
实现 AuthenticationEntryPoint
该接口只有一个方法参数 authException 即 认证错误所抛出的异常 我们根据异常重写reponse 给客户端返回认证错误即可。
我们发现控制台报错
Bad credentials
出现这种错误一般是用户名密码错误,权限不够,密码不匹配等异常。通过debug发现在AbstractUserDetailsAuthenticationProvider
中有以下代码
其实security这样做主要为了安全考虑 (我们也推荐最好不要关闭该开关)但是有小伙伴说我就要抛出UsernameNotFoundException
,没问题。 这里给出三种解决方案(其实是两种,有两种是相同目的不同解决思路)
在登录 (控制台抛出UsernameNotFoundException
)nice
我们其实就是想关闭屏蔽用户名不存在异常的开关,有没有一种方式可以在spring 初始化完DaoAuthenticationProvider后调用前改变对象的属性呢?答案是有, 这就涉及到ioc初始化bean的相关知识 ,在spring ioc 给用户预留一个接口
BeanPostProcessor
ioc会在实例化bean后初始化bean前和后调用该类。类似与aop 。该接口有两个方法postProcessBeforeInitialization
前置处理器 ,postProcessAfterInitialization
后置处理器 。到这里是不是有小伙伴想到怎么做了吗?我们拦截DaoAuthenticationProvider
修改开关属性即可。
注意: ioc容器还有一个给用户预留的接口BeanFactoryPostProcessor
该接口会在ioc 实例化bean之前调用,我们可以实现该接口用于配置bean元数据等信息。想了解更多请看spring官方文档在这里不在展开介绍
/
路径时候控制台出现这是由于我们虽然登录成功了,但是我们禁用了session 所以服务器无法判断当前登录的用户是谁导致没有认证实体
java-jwt
作为token生成包 因为它简单易用tokenService
因为用户登录状态在token中存储在客户端,所以每次请求后台请求头携带token 后台通过自定义token过滤器拦截解析token完成认证并填充用户信息实体。
JwtDecoderFilter
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!