請先閱讀, Spring Boot用3個class輕松實現(xiàn)JWT (一), 保護你的RESTful API
基于前兩部分略做擴展, 和Spring Security集成在了一起.
實現(xiàn)了@PreAuthorize的功能
https://github.com/ZhongjunTian/spring-boot-jwt-demo/tree/master/spring-security-jwt
@GetMapping("/api/admin")
@PreAuthorize("hasAuthority('ADMIN_USER')")
public @ResponseBody
Object helloToAdmin(String userId) {
return "Hello World! You are ADMIN ";
}
和Spring Security集成在一起, 首先要配置, 和前面文章的思想一樣, 我們要允許所有/login的請求, 只對其他請求驗證權(quán)限
Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().authorizeRequests()
.antMatchers("/").permitAll()
.antMatchers(HttpMethod.POST, "/login").permitAll()
.anyRequest().authenticated()
.and()
// We filter the api/** requests
.addFilterBefore(new JwtAuthenticationFilter(),
UsernamePasswordAuthenticationFilter.class);
}
}
配置好了之后, 只需要將之前在Spring Boot用3個class輕松實現(xiàn)JWT (一)那篇文章中提到的JwtAuthenticationFilter添加一行代碼, 將用戶的Role信息注入進去, 然后下一個Filter, 也就是UsernamePasswordAuthenticationFilter就可以得到用戶的信息. 這里生成的UsernamePasswordAuthenticationToken的前兩個入?yún)⒂脩裘兔艽a是null, 因為我們已經(jīng)鑒定過jwt了, 只需要用這個token鑒權(quán).
public class JwtAuthenticationFilter extends OncePerRequestFilter {
//......一些不重要的代碼......
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
try {
if (isProtectedUrl(request)) {
Map<String, Object> claims = JwtUtil.validateTokenAndGetClaims(request);
String role = String.valueOf(claims.get(ROLE));
//最關(guān)鍵的部分就是這里, 我們直接注入了Role信息
SecurityContextHolder.getContext().setAuthentication(
new UsernamePasswordAuthenticationToken(
null, null, Arrays.asList(() -> role)));
}
} catch (Exception e) {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, e.getMessage());
return;
}
filterChain.doFilter(request, response);
}
//......一些不重要的代碼......
}
我們用賬號user, 密碼user拿到普通權(quán)限的jwt之后, 就只能用/api/hello, 而/api/admin則會被spring security攔截報403錯
主要參考了一下兩篇文章, 精簡了70%代碼
https://github.com/nydiarra/springboot-jwt
http://www.baeldung.com/spring-security-oauth-jwt