Spring Security 코드 는 JWT 인터페이스 권한 부여 와 검증 기능 을 실현 합 니 다.
1.환경 준비 작업
csrf().disable()
,즉 크로스 오 버 공격 CSRF 의 방 어 를 잠시 꺼 야 합 니 다.이렇게 하 는 것 은 안전 하지 않 으 니,우 리 는 후속 장 에서 다시 처리 하 자.\#\#2.JWT 도구 류 개발
Maven 좌 표를 통 해 JWT 공구 꾸러미 jjwt 도입
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.0</version>
</dependency>
application.yml 에 JWT 에 대한 사용자 정의 설정 을 추가 합 니 다.
jwt:
header: JWTHeaderName
secret: aabbccdd
expiration: 3600000
@Data
@ConfigurationProperties(prefix = "jwt") // ,prefix
@Component
public class JwtTokenUtil implements Serializable {
private String secret;
private Long expiration;
private String header;
/**
* token
*
* @param userDetails
* @return token
*/
public String generateToken(UserDetails userDetails) {
Map<String, Object> claims = new HashMap<>(2);
claims.put("sub", userDetails.getUsername());
claims.put("created", new Date());
return generateToken(claims);
}
/**
*
*
* @param token
* @return
*/
public String getUsernameFromToken(String token) {
String username;
try {
Claims claims = getClaimsFromToken(token);
username = claims.getSubject();
} catch (Exception e) {
username = null;
}
return username;
}
/**
*
*
* @param token
* @return
*/
public Boolean isTokenExpired(String token) {
try {
Claims claims = getClaimsFromToken(token);
Date expiration = claims.getExpiration();
return expiration.before(new Date());
} catch (Exception e) {
return false;
}
}
/**
*
*
* @param token
* @return
*/
public String refreshToken(String token) {
String refreshedToken;
try {
Claims claims = getClaimsFromToken(token);
claims.put("created", new Date());
refreshedToken = generateToken(claims);
} catch (Exception e) {
refreshedToken = null;
}
return refreshedToken;
}
/**
*
*
* @param token
* @param userDetails
* @return
*/
public Boolean validateToken(String token, UserDetails userDetails) {
SysUser user = (SysUser) userDetails;
String username = getUsernameFromToken(token);
return (username.equals(user.getUsername()) && !isTokenExpired(token));
}
/**
* claims ,
*
* @param claims
* @return
*/
private String generateToken(Map<String, Object> claims) {
Date expirationDate = new Date(System.currentTimeMillis() + expiration);
return Jwts.builder().setClaims(claims)
.setExpiration(expirationDate)
.signWith(SignatureAlgorithm.HS512, secret)
.compact();
}
/**
* ,
*
* @param token
* @return
*/
private Claims getClaimsFromToken(String token) {
Claims claims;
try {
claims = Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody();
} catch (Exception e) {
claims = null;
}
return claims;
}
}
위의 코드 는 io.jsonwebtoken.jwt 가 제공 하 는 방법 으로 JWT 토 큰 생 성,새로 고침 도구 류 를 개발 하 는 것 입 니 다.3.로그 인 인터페이스 개발(Token 인터페이스 획득)
@RESTCONTROLLER
PUBLIC CLASS JWTAUTHCONTROLLER {
@RESOURCE
PRIVATE JWTAUTHSERVICE JWTAUTHSERVICE;
@POSTMAPPING(VALUE = "/AUTHENTICATION")
PUBLIC AJAXRESPONSE LOGIN(@REQUESTBODY MAP<STRING, STRING> MAP) {
STRING USERNAME = MAP.GET("USERNAME");
STRING PASSWORD = MAP.GET("PASSWORD");
IF (STRINGUTILS.ISEMPTY(USERNAME) || STRINGUTILS.ISEMPTY(PASSWORD)) {
RETURN AJAXRESPONSE.ERROR(
NEW CUSTOMEXCEPTION(CUSTOMEXCEPTIONTYPE.USER_INPUT_ERROR," "));
}
RETURN AJAXRESPONSE.SUCCESS(JWTAUTHSERVICE.LOGIN(USERNAME, PASSWORD));
}
@POSTMAPPING(VALUE = "/REFRESHTOKEN")
PUBLIC AJAXRESPONSE REFRESH(@REQUESTHEADER("${JWT.HEADER}") STRING TOKEN) {
RETURN AJAXRESPONSE.SUCCESS(JWTAUTHSERVICE.REFRESHTOKEN(TOKEN));
}
}
핵심 token 비 즈 니스 논 리 는 JwtAuthService 에 적 혀 있 습 니 다.
@Service
public class JwtAuthService {
@Resource
private AuthenticationManager authenticationManager;
@Resource
private UserDetailsService userDetailsService;
@Resource
private JwtTokenUtil jwtTokenUtil;
public String login(String username, String password) {
//
UsernamePasswordAuthenticationToken upToken =
new UsernamePasswordAuthenticationToken( username, password );
Authentication authentication = authenticationManager.authenticate(upToken);
SecurityContextHolder.getContext().setAuthentication(authentication);
// JWT
UserDetails userDetails = userDetailsService.loadUserByUsername( username );
return jwtTokenUtil.generateToken(userDetails);
}
public String refreshToken(String oldToken) {
if (!jwtTokenUtil.isTokenExpired(oldToken)) {
return jwtTokenUtil.refreshToken(oldToken);
}
return null;
}
}
AuthenticationManager 를 사 용 했 기 때문에 웹 보안 ConfigurerAdapter 를 계승 하 는 SpringSecurity 설정 구현 클래스 에서 AuthenticationManager 를 Bean 으로 설명 합 니 다.또한"/authentication"과"/refreshtoken"을 방문 권한 을 개방 하고 접근 권한 을 어떻게 개방 하 는 지 에 대해 서 는 이전 글 에서 말씀 드 렸 습 니 다.
@Bean(name = BeanIds.AUTHENTICATION_MANAGER)
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
4.인터페이스 액세스 인증 필터사용자 가 처음 로그 인 한 후에 우 리 는 JWT 토 큰 을 클 라 이언 트 에 게 되 돌려 주 었 고 클 라 이언 트 는 이 토 큰 을 저장 해 야 합 니 다.인터페이스 요청 을 할 때 영패 테 이 프 를 HTTP 헤더 에 넣 고 헤더 의 이름 은 jwt.header 의 설정 과 일치 해 야 서버 에서 해석 할 수 있 습 니 다.다음은 차단 기 를 정의 합 니 다.
@Slf4j
@Component
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
@Resource
private MyUserDetailsService userDetailsService;
@Resource
private JwtTokenUtil jwtTokenUtil;
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response,
FilterChain chain) throws ServletException, IOException {
// request jwt token
String authHeader = request.getHeader(jwtTokenUtil.getHeader());
log.info("authHeader:{}", authHeader);
// token
if (authHeader != null && StringUtils.isNotEmpty(authHeader)) {
// token
String username = jwtTokenUtil.getUsernameFromToken(authHeader);
if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
//
UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);
// JWT
if (jwtTokenUtil.validateToken(authHeader, userDetails)) {
// 、 、 ,Spring Security
UsernamePasswordAuthenticationToken authentication
= new UsernamePasswordAuthenticationToken(userDetails, null,
userDetails.getAuthorities());
authentication.setDetails(new WebAuthenticationDetailsSource()
.buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(authentication);
}
}
}
chain.doFilter(request, response);
}
}
spring Security 의 설정 클래스(즉 WebSecurity ConfigurerAdapter 구현 클래스 의 configure(HttpSecurity http)설정 방법 에 다음 설정 을 추가 합 니 다.
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
로그 인 인터페이스 테스트,즉 token 인 터 페 이 스 를 가 져 옵 니 다.정확 한 사용자 이름,비밀 번 호 를 입력 하면 token 을 가 져 올 수 있 습 니 다.
다음은 우리 가 정의 하 는 간단 한 인터페이스 인'/hello'를 방문 하지만 JWT 토 큰 을 전달 하지 않 으 면 접근 이 금 지 됩 니 다.이전 단계 에서 돌아 온 token 을 header 에 전달 하면 hello 의 인터페이스 결과 에 정상적으로 응답 할 수 있 습 니 다.
총결산
위 에서 말 한 것 은 소 편 이 소개 한 Spring Security 코드 로 JWT 인터페이스 권한 부여 와 검증 기능 을 실현 하 는 것 입 니 다.여러분 에 게 도움 이 되 기 를 바 랍 니 다.궁금 한 점 이 있 으 시 면 메 시 지 를 남 겨 주세요.소 편 은 제때에 답 해 드 리 겠 습 니 다.여기 서도 저희 사이트 에 대한 여러분 의 지지 에 감 사 드 립 니 다!
만약 당신 이 본문 이 당신 에 게 도움 이 된다 고 생각한다 면,전 재 를 환영 합 니 다.번 거 로 우 시 겠 지만 출처 를 밝 혀 주 십시오.감사합니다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
[MeU] Hashtag 기능 개발➡️ 기존 Tag 테이블에 존재하지 않는 해시태그라면 Tag , tagPostMapping 테이블에 모두 추가 ➡️ 기존에 존재하는 해시태그라면, tagPostMapping 테이블에만 추가 이후에 개발할 태그 기반 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.