WebSecurityConfigurerAdapter loadUserByUsername throws StackOverflow error - java

searched for this but no solution works for me.
So I am trying to have JWT token in my spring boot application. When hitting endpoint /login I`m getting StackOverflow error thrown by WebSecurityConfigurerAdapter$UserDetailsServiceDelegator.loadUserByUsername.
SecurityConfig
#ComponentScan("com.example.javaee_project.security")
#Configuration
#EnableWebSecurity
#RequiredArgsConstructor
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Bean
#Override
public UserDetailsService userDetailsServiceBean() throws Exception{
return super.userDetailsServiceBean();
}
#Bean
public BCryptPasswordEncoder bCryptPasswordEncoderBean() throws Exception{
return new BCryptPasswordEncoder();
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
super.configure(auth);
auth.parentAuthenticationManager(authenticationManagerBean())
.userDetailsService(userDetailsServiceBean())
.passwordEncoder(bCryptPasswordEncoderBean());
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http.authorizeRequests().anyRequest().permitAll();
http.addFilter(new CustomAuthenthicationFilter(authenticationManagerBean()));
}
#Bean
#Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}
CustomAuthenticationFilter
public class CustomAuthenthicationFilter extends UsernamePasswordAuthenticationFilter {
private final AuthenticationManager authenticationManager;
public CustomAuthenthicationFilter(AuthenticationManager authenthicationManager){
this.authenticationManager = authenthicationManager;
}
#Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
String username = request.getParameter("username");
String password = request.getParameter("password");
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, password);
return authenticationManager.authenticate(authenticationToken);
}
#Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException {
User user = (User) authResult.getPrincipal();
Algorithm algorithm = Algorithm.HMAC256("secret".getBytes());
String accessToken = JWT.create()
.withSubject(user.getUsername())
.withExpiresAt(new Date(System.currentTimeMillis() + 10*60*1000))
.withIssuer(request.getRequestURL().toString())
.withClaim("roles", user.getAuthorities().stream().map(GrantedAuthority::getAuthority).collect(Collectors.toList()))
.sign(algorithm);
response.setHeader("access_token", accessToken);
}
}
loadByUsername method in AppUserService
#Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
AppUser user = appUserRepository.findByUsername(username);
Collection<SimpleGrantedAuthority> authorities = new ArrayList<>();
user.getRoles().forEach(role ->
authorities.add(new SimpleGrantedAuthority(role.getName()))
);
if(user != null){
log.info("null user");
throw new UsernameNotFoundException("User not found");
}
return new User(user.getUsername(), user.getPassword(), authorities);
}
}
Main class
#SpringBootApplication(exclude = {SecurityAutoConfiguration.class})
#ComponentScan(basePackages = {"com.example.javaee_project.security"})
public class JavaEeProjectApplication {
public static void main(String[] args) {
SpringApplication.run(JavaEeProjectApplication.class, args);
}
#Bean
PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}

because current AuthenticationManager's parent authenticationManager also delegate current AuthenticationManager
remove SecurityConfig userDetailsServiceBean()
#Bean
#Override
public UserDetailsService userDetailsServiceBean() throws Exception{
return super.userDetailsServiceBean();
}

Related

Cycle between AuthenticationConfiguration and Filters

I have a problem with cycle injection and don't know how to fix it :(
For my SecurityConfig I need JWTAuthenticationFilter.
For my JWTAuthenticationFilter I need AuthenticationManager.
For my AuthenticationManager I need SecurityConfig.
Can you help me with resolving this problem ? Thanks !
#Configuration
#RequiredArgsConstructor
public class ApplicationConfig {
private final UserRepository userRepository;
#Bean
public UserDetailsService userDetailsService() {
return username -> userRepository.findByEmail(username)
.orElseThrow(() -> new UsernameNotFoundException("User not found"));
}
#Bean
public AuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
authProvider.setUserDetailsService(userDetailsService());
authProvider.setPasswordEncoder(passwordEncoder());
return authProvider;
}
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
#Bean
public AuthenticationManager authenticationManager(AuthenticationManagerBuilder auth ) throws Exception {
return auth.userDetailsService(userDetailsService())
.passwordEncoder(passwordEncoder()).and().build();
}
#Bean
public AuthenticationManager authenticationManager(AuthenticationConfiguration config) throws Exception {
return config.getAuthenticationManager();
}
}
#Configuration
#EnableWebSecurity
#RequiredArgsConstructor
public class SecurityConfig {
private final JWTVerifierFilter jwtVerifierFilter;
private final AuthenticationProvider authenticationProvider;
private final JWTAuthenticationFilter jwtAuthenticationFilter;
#Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.csrf()
.disable()
.authorizeHttpRequests()
.requestMatchers("/auth/**")
.permitAll()
.anyRequest()
.authenticated()
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authenticationProvider(authenticationProvider)
.addFilter(jwtAuthenticationFilter)
.addFilterAfter(jwtVerifierFilter, JWTAuthenticationFilter.class);
return http.build();
}
}
#RequiredArgsConstructor
#Component
public class JWTAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
private final AuthenticationManager authenticationManager;
private final TokenRepository tokenRepository;
private final JwtService jwtService;
private final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
#Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
try {
JwtAuthenticationRequest authModel = OBJECT_MAPPER.readValue(request.getInputStream(), JwtAuthenticationRequest.class);
Authentication authentication = new UsernamePasswordAuthenticationToken(authModel.getUsername(), authModel.getPassword());
return authenticationManager.authenticate(authentication);
} catch (IOException e) {
throw new AssertionError(e.getMessage(), e);
}
}
#Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException {
String token = jwtService.generateToken((UserEntity) authResult.getPrincipal());
TokenEntity tokenEntity = TokenEntity.builder()
.id(UUID.randomUUID().toString())
.authenticationToken(token)
.username(authResult.getName())
.build();
tokenEntity = tokenRepository.save(tokenEntity);
response.addHeader(HttpHeaders.AUTHORIZATION, String.format("Bearer %s", tokenEntity.getId()));
ConnValidationResponse respModel = ConnValidationResponse.builder().isAuthenticated(true).build();
response.addHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
response.getOutputStream().write(OBJECT_MAPPER.writeValueAsBytes(respModel));
}
}
I tried to replace
#Bean
public AuthenticationManager authenticationManager(AuthenticationConfiguration config) throws Exception {
return config.getAuthenticationManager();
}
by
#Bean
public AuthenticationManager authenticationManagerBean(HttpSecurity http) throws Exception {
AuthenticationManagerBuilder authenticationManagerBuilder = http.getSharedObject(AuthenticationManagerBuilder.class);
authenticationManagerBuilder.userDetailsService(jwtUserDetailsService).passwordEncoder(passwordEncoder());
return authenticationManagerBuilder.build();
}
but for HttpSecurity I need SecurityConfig too.
I also tried add #Lazy for AuthenticationConfiguration config but it doesn't work

Spring boot securing api with both basic authorization and jwt role based authorization

I am trying to secure my api requests with both basic authorization and jwt role based authorization.
I have two classes for basic auth and web security config. Both jwt role based auth and basic auth classed are imported in WebSecurityConfigurerAdapter.
When running the application, api is working only with basic auth and does not know jwt token included or not.
WebSecurityConfigurerAdapter class
#Configuration
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
final private static String REALM = "UWAPP_SECURITY_REALM";
#Autowired
UserDetailsServiceImpl userDetailsService;
#Autowired
private AuthEntryPointJwt unauthorizedHandler;
#Autowired
public WebSecurityConfig(UserDetailsServiceImpl userDetailsService) {
super();
this.userDetailsService = userDetailsService;
}
#Bean
public AuthTokenFilter authenticationJwtTokenFilter() {
return new AuthTokenFilter();
}
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
#Bean
#Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
.authorizeRequests()
.antMatchers("/actuator/health", "/api/auth/signup", "/api/auth/login", "/api/auth/logout").permitAll()
.antMatchers("/api/test/public").permitAll()
.antMatchers("/api/test/user").hasAnyAuthority(UserLoginRole.USER.value())
.anyRequest().authenticated()
.and()
.formLogin().disable()
.csrf().disable()
.httpBasic().realmName(REALM)
.authenticationEntryPoint(getBasicAuthEntryPoint());
http.addFilterBefore(authenticationJwtTokenFilter(), UsernamePasswordAuthenticationFilter.class);
http.cors();
}
#Bean
public BasicAuthentication getBasicAuthEntryPoint() {
return new BasicAuthentication();
}
}
BasicAuthentication class
public class BasicAuthentication extends BasicAuthenticationEntryPoint {
final private static String REALM = "UWAPP_SECURITY_REALM";
#Override
public void commence(final HttpServletRequest request, final HttpServletResponse response,
final AuthenticationException authException) throws IOException {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.addHeader("WWW-Authenticate", "Basic realm=" + getRealmName() + "");
PrintWriter writer = response.getWriter();
writer.println("HTTP Status 401 : " + authException.getMessage());
}
#Override
public void afterPropertiesSet() {
setRealmName(REALM);
super.afterPropertiesSet();
}
}
Requests did not pass through authorization jwt token included or not.
What am I missing here?

Access denied after changed password with spring boot security JWT

I'm implementing spring boot security for my application. The login function works fine, but somehow whenever I test the change-password function, it's always failed, I checked in the database the password has been updated with the new HashString, but I cannot login with both old-password and new-password. Please help !
Here is the change-password API
#PutMapping("/reset-password")
public ResponseEntity resetPassword(#RequestBody String password){
//extract user name
String username = SecurityContextHolder.getContext().getAuthentication()
.getPrincipal().toString();
ApplicationUser applicationUser = applicationUserRepo.findByUsername(username);
if(applicationUser == null ){
return ResponseEntity.badRequest().body("Could not find UserName");
}
applicationUser.setPassword(bCryptPasswordEncoder.encode(password));
applicationUserRepo.save(applicationUser);
Logs log = new Logs (TimeConverter.getVietnamCurrentTime(),"PASSWORD", "User", applicationUser.getUsername(), applicationUser.getUsername() );
logsRepo.save(log);
return ResponseEntity.ok().body("Password changed successfully!");
}
Here is my implementation of WebSecurityConfigurerAdapter
#EnableWebSecurity
#Configuration
public class WebSecurity extends WebSecurityConfigurerAdapter {
private UserDetailsServiceImpl userDetailsService;
#Autowired
private BCryptPasswordEncoder bCryptPasswordEncoder;
public WebSecurity(UserDetailsServiceImpl userDetailsService, BCryptPasswordEncoder bCryptPasswordEncoder) {
this.userDetailsService = userDetailsService;
this.bCryptPasswordEncoder = bCryptPasswordEncoder;
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable().authorizeRequests()
.antMatchers(HttpMethod.POST, LOGIN_URL).permitAll()
//.antMatchers("/login").permitAll()
.anyRequest().authenticated()
.and()
.addFilter(new JWTAuthenticationFilter(authenticationManager()))
.addFilter(new JWTAuthorizationFilter(authenticationManager()))
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
#Bean
public AuthenticationFailureHandler authenticationFailureHandler() {
return new CustomAuthenticationFailureHandler();
}
#Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder);
}
#Bean
public CorsConfigurationSource corsConfigurationSource() {
final CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(ImmutableList.of("*"));
configuration.setAllowedMethods(ImmutableList.of("HEAD",
"GET", "POST", "PUT", "DELETE", "PATCH"));
configuration.setAllowCredentials(true);
configuration.setAllowedHeaders(ImmutableList.of("Authorization", "Cache-Control", "Content-Type"));
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
#Override
#Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}
AuthenticationFilter
public class JWTAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
private AuthenticationManager authenticationManager;
public JWTAuthenticationFilter(AuthenticationManager authenticationManager) {
this.authenticationManager = authenticationManager;
}
#Override
public Authentication attemptAuthentication(HttpServletRequest req,
HttpServletResponse res) throws AuthenticationException {
try {
ApplicationUser creds = new ObjectMapper()
.readValue(req.getInputStream(), ApplicationUser.class);
return authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(
creds.getUsername(),
creds.getPassword(),
new ArrayList<>())
);
} catch (IOException e) {
System.out.println("fucked");
throw new RuntimeException(e);
}
}
#Override
protected void successfulAuthentication(HttpServletRequest req,
HttpServletResponse res,
FilterChain chain,
Authentication auth) {
String token = JWT.create()
.withSubject(((User) auth.getPrincipal()).getUsername())
.withExpiresAt(new Date(System.currentTimeMillis() + EXPIRATION_TIME))
.sign(HMAC512(SECRET.getBytes()));
res.addHeader(HEADER_STRING, TOKEN_PREFIX + token);
res.addHeader("Access-Control-Expose-Headers","*");
}
#Override
protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed)
throws IOException, ServletException {
response.getWriter().write("blalfaf");
super.unsuccessfulAuthentication(request, response, failed);
}
}
Try using:
addFilterBefore(new JWTAuthenticationFilter(authenticationManager(), UsernamePasswordAuthenticationFilter.class)
instead of just
addFilter(....
in your WebSecurity.configure(.....
This will put your own filter before the original UsernamePasswordAuthenticationFilter. Maybe your filter is last in line and the login is failing before.

I can not retrieve the current custom user object from Spring Security Context

I'm using LDAP authentication provider (active directory) + JWT authorization filter.
I have my custom user object implementing UserDetails, also my user service extends UserDetailsService. But when I do:
Usuario principal = (Usuario) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
Principal is just a string (the username), not my user object.
This is my configuration:
SecurityConfig:
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private final LdapProperties ldapProperties;
private final LdapUserMapper ldapUserMapper;
private final UserService userService;
public SecurityConfig(LdapProperties ldapProperties, LdapUserMapper ldapUserMapper, UserService userService) {
this.ldapProperties = ldapProperties;
this.ldapUserMapper = ldapUserMapper;
this.userService = userService;
}
#Override
protected void configure(HttpSecurity http) throws Exception {
// Entry points
http.authorizeRequests()
.antMatchers(HttpMethod.POST, "/login").permitAll()
.antMatchers(HttpMethod.GET, "/v2/api-docs",
"/configuration/ui",
"/swagger-resources",
"/configuration/security",
"/swagger-ui.html",
"/webjars/**",
"/swagger-resources/**",
"/swagger-ui.html").permitAll()
//TODO review
.anyRequest().authenticated();
// JwtWebSecurityConfigurer... TODO ?
// Filters
http.addFilter(new AuthenticationFilter(authenticationManager())); // ldap
http.addFilter(new AuthorizationFilter(authenticationManager())); // jwt
http.cors();
http.csrf().disable();
// No session will be created or used by spring security
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
// Need to provide Authorization header
http.httpBasic();
}
#Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(ldapAuthenticationProvider());
auth.userDetailsService(userService);
}
#Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration corsConfiguration = new CorsConfiguration().applyPermitDefaultValues();
corsConfiguration.setAllowedMethods(Arrays.asList(CorsConfiguration.ALL));
//TODO configure properly
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", corsConfiguration);
return source;
}
#Bean
public AbstractLdapAuthenticationProvider ldapAuthenticationProvider() {
String urls = "";
for (String url : ldapProperties.getUrls()) {
urls += url + " ";
}
urls = urls.trim();
ActiveDirectoryLdapAuthenticationProvider provider = new ActiveDirectoryLdapAuthenticationProvider(
ldapProperties.getBaseEnvironment().get("domain"),
urls,
ldapProperties.getBase()
);
provider.setUserDetailsContextMapper(ldapUserMapper);
provider.setConvertSubErrorCodesToExceptions(true);
// comment to connect as anonymous
provider.authenticate(
new UsernamePasswordAuthenticationToken(ldapProperties.getUsername(), ldapProperties.getPassword())
);
return provider;
}
}
LdapUserMapper:
#Component
public class LdapUserMapper implements UserDetailsContextMapper {
private final UserService userService;
#Autowired
public LdapUserMapper(UserService userService) {
this.userService = userService;
}
#Override
public UserDetails mapUserFromContext(DirContextOperations ctx, String username, Collection<? extends GrantedAuthority> authorities) {
Usuario result = (Usuario) userService.loadUserByUsername(username);
//TODO compare roles ? set bloqueado ? ...
return result;
}
#Override
public void mapUserToContext(UserDetails userDetails, DirContextAdapter dirContextAdapter) {
}
}
It was my authorization filter.
#Override
protected void doFilterInternal(HttpServletRequest req,
HttpServletResponse res,
FilterChain chain) throws IOException, ServletException {
String token = req.getHeader("Authorization");
if (token != null && token.startsWith("Bearer ")) {
token = token.replace("Bearer ", "");
Authentication authentication = getAuthentication(token);
SecurityContextHolder.getContext().setAuthentication(authentication);
}
chain.doFilter(req, res);
}
private UsernamePasswordAuthenticationToken getAuthentication(final String token) {
try {
DecodedJWT decodedToken = JWT.require(Algorithm.HMAC512(jwtSecret)).build().verify(token);
String username = decodedToken.getSubject();
return new UsernamePasswordAuthenticationToken(username , null, new ArrayList<>());
} catch (JWTVerificationException ex) {
log.error(ex.getMessage());
}
return null;
}
I wasn't aware that I only was passing the username as the Principal object. So I changed it to this:
Usuario usuario = (Usuario) userService.loadUserByUsername(decodedToken.getSubject());
I also removed
auth.userDetailsService(userService);
From AuthenticationManagerBuilder config. That was wrong. My auth provider is LDAP, not the DB.

Approaches for logout functionality in Spring Boot app (Spring Security + JWT)

I create Spring Boot + Spring Security app with JWT authentication and it works something like this:
client sends username, password to the login endpoint;
server checks if the provided credentials are valid and return a token;
client sends the token with every future request.
It's based on this example and approach for logout functionality which author suggest - just remove JWT token on client-side. I don't think that is good idea, and I'd like to implement it on back-end.
As I understand I need to remove JWT token of user which call logout REST method on server-side, after that when this user will call other REST methods he should get responses with 403 error. I investigated ways how can I add this feature and didn't find any appropriate solution.
Here are details of my implementation (there may be some differences from the example from the link above):
#EnableWebSecurity
public class WebSecurity extends WebSecurityConfigurerAdapter {
private UserDetailsService userDetailsService;
private BCryptPasswordEncoder bCryptPasswordEncoder;
public WebSecurity(UserDetailsService userDetailsService, BCryptPasswordEncoder bCryptPasswordEncoder) {
this.userDetailsService = userDetailsService;
this.bCryptPasswordEncoder = bCryptPasswordEncoder;
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable().authorizeRequests()
.antMatchers(HttpMethod.POST, SIGN_UP_URL).permitAll()
.antMatchers(HttpMethod.POST, LOGIN_URL).permitAll()
.antMatchers(HttpMethod.GET, HEALTH_URL).permitAll()
.anyRequest().authenticated()
.and()
.addFilter(new JWTAuthenticationFilter(authenticationManager()))
.addFilter(new JWTAuthorizationFilter(authenticationManager()))
// this disables session creation on Spring Security
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
#Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder);
}
#Bean
CorsConfigurationSource corsConfigurationSource() {
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", new CorsConfiguration().applyPermitDefaultValues());
return source;
}
}
public class JWTAuthorizationFilter extends BasicAuthenticationFilter {
public JWTAuthorizationFilter(AuthenticationManager authManager) {
super(authManager);
}
#Override
protected void doFilterInternal(HttpServletRequest req,
HttpServletResponse res,
FilterChain chain) throws IOException, ServletException {
String header = req.getHeader(HEADER_STRING);
if (header == null || !header.startsWith(TOKEN_PREFIX)) {
chain.doFilter(req, res);
return;
}
UsernamePasswordAuthenticationToken authentication = getAuthentication(req);
SecurityContextHolder.getContext().setAuthentication(authentication);
chain.doFilter(req, res);
}
private UsernamePasswordAuthenticationToken getAuthentication(HttpServletRequest request) {
String token = request.getHeader(HEADER_STRING);
if (token != null) {
String user = Jwts.parser()
.setSigningKey(SECRET.getBytes())
.parseClaimsJws(token.replace(TOKEN_PREFIX, ""))
.getBody()
.getSubject();
if (user != null) {
return new UsernamePasswordAuthenticationToken(user, null, new ArrayList<>());
}
return null;
}
return null;
}
}
public class JWTAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
private AuthenticationManager authenticationManager;
public JWTAuthenticationFilter(AuthenticationManager authenticationManager) {
this.authenticationManager = authenticationManager;
setFilterProcessesUrl(LOGIN_URL);
}
#Override
public Authentication attemptAuthentication(HttpServletRequest req,
HttpServletResponse res) throws AuthenticationException {
try {
User creds = new ObjectMapper().readValue(req.getInputStream(), User.class);
return authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(
creds.getUsername(),
creds.getPassword(),
new ArrayList<>())
);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
#Override
protected void successfulAuthentication(HttpServletRequest req,
HttpServletResponse res,
FilterChain chain,
Authentication auth) throws IOException, ServletException {
String token = Jwts.builder()
.setSubject(((org.springframework.security.core.userdetails.User) auth.getPrincipal()).getUsername())
.setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME))
.signWith(SignatureAlgorithm.HS512, SECRET.getBytes())
.compact();
res.addHeader(HEADER_STRING, TOKEN_PREFIX + token);
}
}
public class SecurityConstants {
public static final String SECRET = "SecretKeyToGenJWTs";
public static final long EXPIRATION_TIME = 864_000_000; // 10 days
public static final String TOKEN_PREFIX = "Bearer ";
public static final String HEADER_STRING = "Authorization";
}

Categories