Xóa bài viết
Bạn có chắc chắn muốn xóa bài viết này không ?
Xóa bình luận
Bạn có chắc chắn muốn xóa bình luận này không ?
[Spring Security + JWT] Phần 3 - Đọc JWT và làm một vài api test permission
Ở phần 2 mình đã tạo ra token và làm cái api đăng nhập rồi trả về token. ở phần này mình sẽ đọc thông tin từ cái token đó xử lý nó và làm thử cái api test quyền truy cập nhé
Chiến luôn thôi
Tạo method đọc JWT này
private JWTClaimsSet getClaimsFromToken(String token) {
JWTClaimsSet claims = null;
try {
SignedJWT signedJWT = SignedJWT.parse(token);
JWSVerifier verifier = new MACVerifier(SECRET.getBytes());
if (signedJWT.verify(verifier)) {
claims = signedJWT.getJWTClaimsSet();
}
} catch (ParseException | JOSEException e) {
logger.error(e.getMessage());
}
return claims;
}
public UserPrincipal getUserFromToken(String token) {
UserPrincipal user = null;
try {
JWTClaimsSet claims = getClaimsFromToken(token);
if (claims != null && isTokenExpired(claims)) {
JSONObject jsonObject = (JSONObject) claims.getClaim(USER);
user = new ObjectMapper().readValue(jsonObject.toJSONString(), UserPrincipal.class);
}
} catch (Exception e) {
logger.error(e.getMessage());
}
return user;
}
private Date getExpirationDateFromToken(JWTClaimsSet claims) {
return claims != null ? claims.getExpirationTime() : new Date();
}
private boolean isTokenExpired(JWTClaimsSet claims) {
return getExpirationDateFromToken(claims).after(new Date());
}
- Đây nhé trong method
getClaimsFromToken
ta sẽ lấy raJWTClaimsSet
, trong đây phải có đúng chuỗiSECRET
đã tạo ra token mới lấy ra được JWTClaimsSet. - Method
getUserFromToken
ta sẽ lấy ra cái thằngUserPrincipal
hôm trước đã tạo và cho vào trong token
Method lấy token trong database
TokenRepository
Token findByToken(String token);
TokenService
Token findByToken(String token);
TokenService
@Override
public Token findByToken(String token) {
return tokenRepository.findByToken(token);
}
Tạo class filter
@Component
public class JwtRequestFilter extends OncePerRequestFilter {
@Autowired
private JwtUtil jwtUtil;
@Autowired
private TokenService verificationTokenService;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
final String authorizationHeader = request.getHeader("Authorization");
UserPrincipal user = null;
Token token = null;
if (StringUtils.hasText(authorizationHeader) && authorizationHeader.startsWith("Token ")) {
String jwt = authorizationHeader.substring(6);
user = jwtUtil.getUserFromToken(jwt);
token = verificationTokenService.findByToken(jwt);
}
if (null != user && null != token && token.getTokenExpDate().after(new Date())) {
Set<GrantedAuthority> authorities = new HashSet<>();
user.getAuthorities().forEach(p -> authorities.add(new SimpleGrantedAuthority((String) p)));
UsernamePasswordAuthenticationToken authentication =
new UsernamePasswordAuthenticationToken(user, null, authorities);
authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(authentication);
}
filterChain.doFilter(request, response);
}
}
- Ở đây mình extend từ
OncePerRequestFilter
thằng này sẽ chỉ thực hiện một lần filter trong mỗi request. - Trong đây mình sẽ kiểm tra trong header của mỗi request có thằng
Authorization
với giá trị bắt đầu làToken
(ví dụ:Token abcdaw123cas.asdawe...
) thì mình mới xử lý. - Sau khi kiểm tra token hợp lệ, thì mình sẽ phải set vào trong
SecurityContextHolder.getContext().setAuthentication()
. Đây chính là cái phần mà chỗ set vào của chỗ mình bảoUserPrincipal
có thể lấy được bất kỳ đâu trong ứng dụng, là nó được tạo dữ liệu từ đây.
Thêm filter security config
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private JwtRequestFilter jwtRequestFilter;
@Override
public void configure(HttpSecurity http) throws Exception {
http.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class)
.csrf().disable();
}
}
-
@EnableGlobalMethodSecurity(prePostEnabled = true)
cái này sẽ giúp mình có thể kiểm soát security đến từng phương thức. Ở đâyprePostEnabled = true
mình sẽ sử dụng được 2 annotation@PreAuthorize
và@PostAuthorize
để phân quyền.
Thêm api test permission
@GetMapping("/hello")
@PreAuthorize("hasAnyAuthority('USER_READ')")
public ResponseEntity hello(){
return ResponseEntity.ok("hello");
}
Test thử api
mọi thứ đều chuẩn nó sẽ thế này
đây là khi token sai
đây là không có quyền vào role
Thêm 2 annotation @CreatedBy và @LastModifiedBy
Thêm vào BaseEntity
@CreatedBy
private Long createdBy;
@LastModifiedBy
private Long updatedBy;
Class cái gì đó AuditorAware
@Component
public class SpringSecurityAuditorAware implements AuditorAware<Long> {
@Override
public Optional<Long> getCurrentAuditor() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication == null || !authentication.isAuthenticated()) {
return null;
}
if (authentication.getPrincipal()=="anonymousUser"){
return Optional.of(0l);
}
return Optional.of(((UserPrincipal) authentication.getPrincipal()).getUserId());
}
}
- mình đặt tên là
SpringSecurityAuditorAware
vì mình không biết đặt tên gì nữa :D. Đó giờ là 2 cái annotation kia đã hoạt động được rồi.
Tổng kết
- Sau 3 phần mình có gì nào:
- Một cái web service cơ bản theo mô hình 3 lớp.
- Đọc ghi JWT.
- Phân quyền theo chức năng đến từng method này.
- ...
-
Tính sơ sơ là có vậy thôi. để xem lại
Github đây là project của mình, các bạn có góp ý gì comment ở dưới giúp mình với!
Cảm ơn các bạn đã theo dõi đến đây nhé!!! thả cho cái tim
Bình luận

{{ comment.user.name }}
Bỏ hay
Hay

Cùng một tác giả

8
0
Xin chào các bạn đọc, trong seri này mình dự định sẽ chia sẻ cách dùng spring security để phân quyền trong web service, cách đọc ghi một JWT, rồi t...

7
1
Restful api Rest (Representational State Transfer) hiểu nôm na nó là một kiểu kiến trúc được dùng để giao tiếp giữa các máy tính, được truyền tải...

4
0
Ở (Link) mình đã tạo một số model và tạo thử một api register, ở phần này mình sẽ hướng dẫn các bạn tạo một chuỗi JWT và khi login sẽ chả về cái ch...
Bài viết liên quan

0
0
https://loizenai.com/reactjsjwtauthenticationexample/ Reactjs JWT Authentication Example Tutorial: Reactjs JWT Token Authentication Example J...

0
0
https://grokonez.com/frontend/angular/angular6/angularspringbootjwtauthenticationexampleangular6springsecuritymysqlfullstackpart3buildfrontend The...

1
0
Angular Spring Boot jwt Authentication Example Github https://loizenai.com/angularspringbootjwt/ (Ảnh) Tutorial: ” Angular Spring Boot jwt Authe...