-
Notifications
You must be signed in to change notification settings - Fork 6.1k
Closed
Labels
for: stackoverflowA question that's better suited to stackoverflow.comA question that's better suited to stackoverflow.com
Description
I am trying to implement jwt authentication with spring webflux and i am adding filter on SecurityWebFiltersOrder.AUTHENTICATION but the problem is its getting called on permitted urls too.
@Configuration
@EnableWebFluxSecurity
public class SecurityConfig {
@Bean
public SecurityWebFilterChain securityWebFilterChain(
ServerHttpSecurity http,
ReactiveAuthenticationManager jwtAuthenticationManager,
ServerAuthenticationConverter jwtAuthenticationConverter
) {
AuthenticationWebFilter authenticationWebFilter = new AuthenticationWebFilter(jwtAuthenticationManager);
authenticationWebFilter.setServerAuthenticationConverter(jwtAuthenticationConverter);
return http
.addFilterAt(authenticationWebFilter, SecurityWebFiltersOrder.AUTHENTICATION)
.httpBasic()
.disable()
.csrf()
.disable()
.formLogin()
.disable()
.logout()
.disable()
.exceptionHandling()
.authenticationEntryPoint((exchange, e) -> {
if (e.getCause() instanceof AccessDeniedException) {
throw new ForbiddenException(e);
}
throw new UnauthorizedException(e);
})
.and()
.authorizeExchange()
.pathMatchers(
"/api/auth/login"
).permitAll()
.pathMatchers("/api/user/**").hasRole(RolesList.SUPER_ADMIN.name())
.pathMatchers("/api/auth/password").hasAnyRole(RolesList.SUPER_ADMIN.name(), RolesList.ADMIN.name())
.pathMatchers("/api/**").authenticated() //entire server side app will be kept here
.anyExchange().permitAll() // every else path should be permitted
.and()
.build();
}
}
@Component
public class JwtServerAuthenticationConverter implements ServerAuthenticationConverter {
private static final String AUTH_HEADER_VALUE_PREFIX = "Bearer ";
@Override
public Mono<Authentication> convert(ServerWebExchange exchange) {
System.out.println("convert called");
return Mono.justOrEmpty(exchange)
.flatMap(serverWebExchange -> Mono.justOrEmpty(
serverWebExchange
.getRequest()
.getHeaders()
.getFirst(HttpHeaders.AUTHORIZATION)
)
)
.filter(header -> !header.trim().isEmpty() && header.trim().startsWith(AUTH_HEADER_VALUE_PREFIX))
.map(header -> header.substring(AUTH_HEADER_VALUE_PREFIX.length()))
.map(token -> new UsernamePasswordAuthenticationToken(token, token))
;
}
}
@Component
public class JwtAuthenticationManager implements ReactiveAuthenticationManager {
private final JWTProperties jwtProperties;
private final ObjectMapper objectMapper;
public JwtAuthenticationManager(JWTProperties jwtProperties, ObjectMapper objectMapper) {
this.jwtProperties = jwtProperties;
this.objectMapper = objectMapper;
}
@Override
public Mono<Authentication> authenticate(Authentication authentication) {
return Mono.just(authentication)
.map(auth -> JWTHelper.loadAllClaimsFromToken(auth.getCredentials().toString(), jwtProperties.getSecret()))
.onErrorResume(throwable -> Mono.error(new UnauthorizedException()))
.map(claims -> objectMapper.convertValue(claims, JWTUserDetails.class))
.map(jwtUserDetails ->
new UsernamePasswordAuthenticationToken(
jwtUserDetails,
authentication.getCredentials(),
jwtUserDetails.getGrantedAuthorities()
)
)
;
}
}
As you can see /api/auth/login path should not check the jwt token but when i hit it i can see convert called on the console
while i am assuming that is should only get called for authenticated urls.
Metadata
Metadata
Assignees
Labels
for: stackoverflowA question that's better suited to stackoverflow.comA question that's better suited to stackoverflow.com