В настоящее время я работаю над проектом с использованием среды Spring, мне хотелось реализовать процесс аутентификации и авторизации JWT. Поэтому я добавил свой собственный класс JwtAuthenticationFilter, который расширяет класс UsernamePasswordAuthenticationFilter в мою конфигурацию безопасности.
Если данные для входа, отправленные клиентом, совпадают с данными, хранящимися в базе данных, JwtAuthenticationFilter должен будет выдать Токен JWT, сохраните его в заголовке ответа и отправьте.
Поэтому я переопределил функцию "successfulAuthentication", объявленную в классе "UsernamePasswordAuthenticationFilter", и поместил логику выдачи токена JWT в переопределенную функцию. .
Но код не работал так, как я ожидал, он постоянно показывал мне ошибку 404 Not Found по ссылке "/". Я понятия не имел, почему Spring запрашивает «/» во время обработки. (Я не установил «/» в качестве URL-адреса успешного входа в систему)
Поэтому вместо этого я объявил объект AuthenticationSuccessHandler, установил его как аутентификацию фильтра. обработчик успеха с помощью AuthenticationManager и переместил логику выдачи токенов в обработчик. И это сработало, как я и ожидал.
Я не понимаю разницы между успешной аутентификацией и аутентификациейSuccessHandler. Даже если я ищу, мне только говорят, что использование этих двух функций является выбором разработчика.
Однако, даже если я использую одну и ту же логику выдачи токенов, я думаю, что разница в поведение этих двух кодов определенно связано с чем-то разным.
JwtAuthenticationFilter
Код: Выделить всё
public class JwtAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
//try-catch?
@Override
public Authentication attemptAuthentication(HttpServletRequest request,
HttpServletResponse response) throws AuthenticationException {
try {
ObjectMapper objectMapper = new ObjectMapper();
Map requestData = objectMapper.readValue(request.getInputStream(), Map.class);
String memberId = requestData.get("member_id");
String memberPw = requestData.get("member_pw");
UsernamePasswordAuthenticationToken authToken =
new UsernamePasswordAuthenticationToken(memberId, memberPw);
Authentication authentication = getAuthenticationManager().authenticate(authToken);
UserDetails principal = (UserDetails) authentication.getPrincipal();
log.debug("username : {}", principal.getUsername());
log.debug("authority : {}", principal.getAuthorities());
return authentication;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException {
super.successfulAuthentication(request, response, chain, authResult);
}
}
Код: Выделить всё
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception{
http
.authorizeHttpRequests((authorizeRequests) ->
authorizeRequests
.requestMatchers("/", "/login", "/error", "/register").permitAll()
.requestMatchers("/student/**").hasRole(MemberRole.Student.name())
.requestMatchers("/professor/**").hasRole(MemberRole.Professor.name())
.anyRequest().authenticated()
)
.csrf((csrfConfig) ->
csrfConfig.disable()
)
.httpBasic((httpBasieConfig) ->
httpBasieConfig.disable()
)
.formLogin((formLoginConfig) ->
formLoginConfig.disable()
)
.sessionManagement((sessionConfig) ->
sessionConfig.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
)
.addFilter(getJwtAuthenticationFilter())
.addFilterBefore(getJwtAuthorizationFilter(), UsernamePasswordAuthenticationFilter.class)
.logout((logout) ->
logout.logoutSuccessUrl("/")
)
.exceptionHandling((exceptionConfig) ->
exceptionConfig.authenticationEntryPoint(authenticationEntryPoint).accessDeniedHandler(accessDeniedHandler)
);
return http.build();
}
@Bean
public JwtAuthenticationFilter getJwtAuthenticationFilter() throws Exception{
JwtAuthenticationFilter jwtAuthenticationFilter = new JwtAuthenticationFilter();
AuthenticationManagerBuilder builder = new AuthenticationManagerBuilder(objectPostProcessor);
jwtAuthenticationFilter.setAuthenticationManager(authenticationManager(builder));
jwtAuthenticationFilter.setAuthenticationSuccessHandler(authenticationSuccessHandler);
return jwtAuthenticationFilter;
}
private AuthenticationManager authenticationManager(AuthenticationManagerBuilder auth) throws Exception{
auth.userDetailsService(memberService).passwordEncoder(passwordEncoder());
return auth.build();
}
private AuthenticationSuccessHandler authenticationSuccessHandler = (((request, response, authentication) -> {
SecurityContextHolder.getContext().setAuthentication(authentication);
long expirationTime = 864_000_000;
Ключевой ключ = Keys.hmacShaKeyFor(secretKey.getBytes(StandardCharsets.UTF_8));
String jwtToken = Jwts.builder()
.setSubject(authentication.getName())
.claim("authorities", аутентификация.getAuthorities().stream()< br /> .map(GrantedAuthority::getAuthority).collect(Collectors.toList()))
.setIssuedAt(new Date(System.currentTimeMillis()))
.setExpiration(new Date(System. currentTimeMillis() + expirationTime))
.signWith(key, SignatureAlgorithm.HS512)
.compact();
NormalResponsenormalResponse = new NormalResponse(HttpStatus.OK, «Аутентификация успешна) ");
String responseBody = objectMapper.writeValueAsString(normalResponse);
response.setContentType("application/json");
response.addHeader("Аутентификация", "Носитель" " + jwtToken);
response.getWriter().write(responseBody);
}));
Может кто-нибудь объяснить??
Источник: https://stackoverflow.com/questions/781 ... tionsucces