Java SpringSecurity+JWT實現(xiàn)登錄認(rèn)證
前言:
學(xué)習(xí)過我的mall項目的應(yīng)該知道,mall-admin模塊是使用SpringSecurity+JWT來實現(xiàn)登錄認(rèn)證的,而mall-portal模塊是使用的SpringSecurity基于Session的默認(rèn)機(jī)制來實現(xiàn)登陸認(rèn)證的。很多小伙伴都找不到mall-portal的登錄接口,最近我把這兩個模塊的登錄認(rèn)證給統(tǒng)一了,都使用SpringSecurity+JWT的形式實現(xiàn)。主要是通過把登錄認(rèn)證的通用邏輯抽取到了mall-security模塊來實現(xiàn)的,下面我們講講如何使用mall-security模塊來實現(xiàn)登錄認(rèn)證,僅需四步即可。
整合步驟
這里我們以
mall-portal改造為例來說說如何實現(xiàn)。
第一步,給需要登錄認(rèn)證的模塊添加mall-security依賴:
<dependency>
<groupId>com.macro.mall</groupId>
<artifactId>mall-security</artifactId>
</dependency>
第二步,添加MallSecurityConfig配置類,繼承mall-security中的SecurityConfig配置,并且配置一個UserDetailsService接口的實現(xiàn)類,用于獲取登錄用戶詳情:
/**
* mall-security模塊相關(guān)配置
* Created by macro on 2019/11/5.
*/
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled=true)
publicclass MallSecurityConfig extends SecurityConfig {
@Autowired
private UmsMemberService memberService;
@Bean
public UserDetailsService userDetailsService() {
//獲取登錄用戶信息
return username -> memberService.loadUserByUsername(username);
}
}
第三步,在application.yml中配置下不需要安全保護(hù)的資源路徑:
secure:
ignored:
urls:#安全路徑白名單
-/swagger-ui.html
-/swagger-resources/**
-/swagger/**
-/**/v2/api-docs
-/**/*.js
-/**/*.css
-/**/*.png
-/**/*.ico
-/webjars/springfox-swagger-ui/**
-/druid/**
-/actuator/**
-/sso/**
-/home/**
第四步,在UmsMemberController中實現(xiàn)登錄和刷新token的接口:
/**
* 會員登錄注冊管理Controller
* Created by macro on 2018/8/3.
*/
@Controller
@Api(tags = "UmsMemberController", description = "會員登錄注冊管理")
@RequestMapping("/sso")
publicclass UmsMemberController {
@Value("${jwt.tokenHeader}")
private String tokenHeader;
@Value("${jwt.tokenHead}")
private String tokenHead;
@Autowired
private UmsMemberService memberService;
@ApiOperation("會員登錄")
@RequestMapping(value = "/login", method = RequestMethod.POST)
@ResponseBody
public CommonResult login(@RequestParam String username,
@RequestParam String password) {
String token = memberService.login(username, password);
if (token == null) {
return CommonResult.validateFailed("用戶名或密碼錯誤");
}
Map<String, String> tokenMap = new HashMap<>();
tokenMap.put("token", token);
tokenMap.put("tokenHead", tokenHead);
return CommonResult.success(tokenMap);
}
@ApiOperation(value = "刷新token")
@RequestMapping(value = "/refreshToken", method = RequestMethod.GET)
@ResponseBody
public CommonResult refreshToken(HttpServletRequest request) {
String token = request.getHeader(tokenHeader);
String refreshToken = memberService.refreshToken(token);
if (refreshToken == null) {
return CommonResult.failed("token已經(jīng)過期!");
}
Map<String, String> tokenMap = new HashMap<>();
tokenMap.put("token", refreshToken);
tokenMap.put("tokenHead", tokenHead);
return CommonResult.success(tokenMap);
}
}實現(xiàn)原理
將SpringSecurity+JWT的代碼封裝成通用模塊后,就可以方便其他需要登錄認(rèn)證的模塊來使用,下面我們來看看它是如何實現(xiàn)的,首先我們看下
mall-security的目錄結(jié)構(gòu)。
目錄結(jié)構(gòu)
mall-security
├── component
| ├── JwtAuthenticationTokenFilter -- JWT登錄授權(quán)過濾器
| ├── RestAuthenticationEntryPoint -- 自定義返回結(jié)果:未登錄或登錄過期
| └── RestfulAccessDeniedHandler -- 自定義返回結(jié)果:沒有權(quán)限訪問時
├── config
| ├── IgnoreUrlsConfig -- 用于配置不需要安全保護(hù)的資源路徑
| └── SecurityConfig -- SpringSecurity通用配置
└── util
└── JwtTokenUtil -- JWT的token處理工具類
做了哪些變化
其實我也就添加了兩個類,一個IgnoreUrlsConfig,用于從application.yml中獲取不需要安全保護(hù)的資源路徑。一個SecurityConfig提取了一些SpringSecurity的通用配置。
IgnoreUrlsConfig中的代碼:
/**
* 用于配置不需要保護(hù)的資源路徑
* Created by macro on 2018/11/5.
*/
@Getter
@Setter
@ConfigurationProperties(prefix = "secure.ignored")
publicclass IgnoreUrlsConfig {
private List<String> urls = new ArrayList<>();
}
SecurityConfig中的代碼:
/**
* 對SpringSecurity的配置的擴(kuò)展,支持自定義白名單資源路徑和查詢用戶邏輯
* Created by macro on 2019/11/5.
*/
publicclass SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry = httpSecurity
.authorizeRequests();
//不需要保護(hù)的資源路徑允許訪問
for (String url : ignoreUrlsConfig().getUrls()) {
registry.antMatchers(url).permitAll();
}
//允許跨域請求的OPTIONS請求
registry.antMatchers(HttpMethod.OPTIONS)
.permitAll();
// 任何請求需要身份認(rèn)證
registry.and()
.authorizeRequests()
.anyRequest()
.authenticated()
// 關(guān)閉跨站請求防護(hù)及不使用session
.and()
.csrf()
.disable()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
// 自定義權(quán)限拒絕處理類
.and()
.exceptionHandling()
.accessDeniedHandler(restfulAccessDeniedHandler())
.authenticationEntryPoint(restAuthenticationEntryPoint())
// 自定義權(quán)限攔截器JWT過濾器
.and()
.addFilterBefore(jwtAuthenticationTokenFilter(), UsernamePasswordAuthenticationFilter.class);
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService())
.passwordEncoder(passwordEncoder());
}
@Bean
public PasswordEncoder passwordEncoder() {
returnnew BCryptPasswordEncoder();
}
@Bean
public JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter() {
returnnew JwtAuthenticationTokenFilter();
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
returnsuper.authenticationManagerBean();
}
@Bean
public RestfulAccessDeniedHandler restfulAccessDeniedHandler() {
returnnew RestfulAccessDeniedHandler();
}
@Bean
public RestAuthenticationEntryPoint restAuthenticationEntryPoint() {
returnnew RestAuthenticationEntryPoint();
}
@Bean
public IgnoreUrlsConfig ignoreUrlsConfig() {
returnnew IgnoreUrlsConfig();
}
@Bean
public JwtTokenUtil jwtTokenUtil() {
returnnew JwtTokenUtil();
}
}到此這篇關(guān)于Java SpringSecurity+JWT實現(xiàn)登錄認(rèn)證 的文章就介紹到這了,更多相關(guān)Java SpringSecurity 內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JAVA生成八位不重復(fù)隨機(jī)數(shù)最快的方法總結(jié)(省時間省空間)
隨機(jī)數(shù)在實際中使用很廣泛,比如要隨即生成一個固定長度的字符串、數(shù)字,這篇文章主要給大家介紹了關(guān)于JAVA生成八位不重復(fù)隨機(jī)數(shù)最快的方法,文中介紹的方法省時間省空間,需要的朋友可以參考下2024-03-03
SpringBoot整合RabbitMQ實現(xiàn)六種工作模式的示例
這篇文章主要介紹了SpringBoot整合RabbitMQ實現(xiàn)六種工作模式,本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-07-07
Invalid bound statement(not found):錯誤的解決方案
本文介紹了在開發(fā)Java SpringBoot應(yīng)用程序時出現(xiàn)的"Invalidboundstatement(notfound)"錯誤的原因及解決方法,該錯誤通常與MyBatis或其他持久化框架相關(guān),可能是由于配置錯誤、拼寫錯誤或其他問題引起的,解決方法包括檢查SQL映射文件2025-01-01
Spring+Quartz配置定時任務(wù)實現(xiàn)代碼
這篇文章主要介紹了Spring+Quartz配置定時任務(wù)實現(xiàn)代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-04-04

