Skip to main content
Stack Overflow
  1. About
  2. For Teams

Return to Question

Notice removed Draw attention by Community Bot
Bounty Ended with no winning answer by Community Bot
added 442 characters in body
Source Link
Stephane
  • 12.9k
  • 28
  • 127
  • 188
@Component
public class CustomAuthenticationProvider implements AuthenticationProvider {
 @Autowired
 CredentialsService credentialsService;
 @Override
 public Authentication authenticate(Authentication authentication) throws AuthenticationException {
 String email = authentication.getName();
 String password = authentication.getCredentials().toString();
 List<SimpleGrantedAuthority> grantedAuthorities = new ArrayList<SimpleGrantedAuthority>();
 User user = null;
 try {
 user = credentialsService.findByEmail(new EmailAddress(email));
 } catch (IllegalArgumentException e) {
 throw new BadCredentialsException("The login " + email + " and password could not match."); 
 }
 if (user != null) {
 if (credentialsService.checkPassword(user, password)) {
 grantedAuthorities.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
 return new UsernamePasswordAuthenticationToken(email, password, grantedAuthorities);
 } else {
 throw new BadCredentialsException("The login " + user.getEmail() + " and password could not match."); 
 }
 }
 throw new BadCredentialsException("The login " + authentication.getPrincipal() + " and password could not match.");
 }
 @Override
 public boolean supports(Class<?> authentication) {
 return authentication.equals(UsernamePasswordAuthenticationToken.class);
 }
 @Bean
 public static NoOpPasswordEncoder passwordEncoder() {
 return (NoOpPasswordEncoder) NoOpPasswordEncoder.getInstance();
 }
}
@Component
public class AuthenticationFromTokenFilter extends GenericFilterBeanOncePerRequestFilter {
 @Autowired
 private TokenAuthenticationService tokenAuthenticationService;
 @Override
 publicprotected void doFilterdoFilterInternal(ServletRequestHttpServletRequest request, ServletResponseHttpServletResponse response, FilterChain chain)
 throws IOException, ServletException {
 HttpServletRequest httpRequest = getAsHttpRequest(request);
 tokenAuthenticationService.authenticateFromToken(httpRequestrequest);
 chain.doFilter(request, response);
 }
 private HttpServletRequest getAsHttpRequest(ServletRequest request) {
 if (!(request instanceof HttpServletRequest)) {
 throw new RuntimeException("The request was not an HTTP request");
 }
 return (HttpServletRequest) request;
 }
}
@Service
public class TokenAuthenticationServiceImpl implements TokenAuthenticationService {
 private static Logger logger = LoggerFactory.getLogger(TokenAuthenticationServiceImpl.class);
 private static final long ONE_WEEK = 1000 * 60 * 60 * 24 * 7;
 private static final String TOKEN_URL_PARAM_NAME = "token";
 
 @Autowired
 private ApplicationProperties applicationProperties;
 @Autowired
 private UserDetailsService userDetailsService;
 public void addTokenToResponseHeader(HttpHeaders headers, String username) {
 String token = buildToken(username);
 headers.add(CommonConstants.AUTH_HEADER_NAME, token);
 }
 
 public void addTokenToResponseHeader(HttpServletResponse response, Authentication authentication) {
 String username = authentication.getName();
 if (username != null) {
 String token = buildToken(username);
 response.addHeader(CommonConstants.AUTH_HEADER_NAME, token);
 }
 }
 private String buildToken(String username) {
 String token = null;
 UserDetails userDetails = userDetailsService.loadUserByUsername(username);
 if (userDetails != null) {
 Date expirationDate = new Date(System.currentTimeMillis() + ONE_WEEK);
 token = CommonConstants.AUTH_BEARER + " " + Jwts.builder().signWith(HS256, getEncodedPrivateKey()).setExpiration(expirationDate).setSubject(userDetails.getUsername()).compact(); 
 }
 return token;
 }
 
 public Authentication authenticateFromToken(HttpServletRequest request) {
 String token = extractAuthTokenFromRequest(request);
 logger.debug("The request contained the JWT token: " + token);
 if (token != null && !token.isEmpty()) {
 try {
 String username = Jwts.parser().setSigningKey(getEncodedPrivateKey()).parseClaimsJws(token).getBody().getSubject();
 if (username != null) {
 UserDetails userDetails = userDetailsService.loadUserByUsername(username);
 UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
 authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
 SecurityContextHolder.getContext().setAuthentication(authentication);
 logger.debug("Security - The filter authenticated fine from the JWT token");
 }
 } catch (SignatureException e) {
 logger.info("The JWT token " + token + " could not be parsed.");
 }
 }
 return null;
 }
 private String extractAuthTokenFromRequest(HttpServletRequest request) {
 String token = null;
 String header = request.getHeader(CommonConstants.AUTH_HEADER_NAME);
 if (header != null && header.contains(CommonConstants.AUTH_BEARER)) {
 int start = (CommonConstants.AUTH_BEARER + " ").length();
 if (header.length() > start) {
 token = header.substring(start - 1);
 }
 } else {
 // The token may be set as an HTTP parameter in case the client could not set it as an HTTP header
 token = request.getParameter(TOKEN_URL_PARAM_NAME);
 }
 return token;
 }
 private String getEncodedPrivateKey() {
 String privateKey = applicationProperties.getAuthenticationTokenPrivateKey();
 return Base64.getEncoder().encodeToString(privateKey.getBytes());
 }
 
}
@Configuration
@EnableWebSecurity
@ComponentScan(nameGenerator = PackageBeanNameGenerator.class, basePackages = { "com.thalasoft.user.rest.security", "com.thalasoft.user.rest.filter" })
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
 @Override@Autowired
 protectedprivate voidUserDetailsService configure(AuthenticationManagerBuilderuserDetailsService;
 authenticationManagerBuilder 
 @Autowired
 private AuthenticationFromTokenFilter authenticationFromTokenFilter;
 
 @Autowired
 private SimpleCORSFilter simpleCORSFilter;
 
 @Autowired
 private RESTAuthenticationEntryPoint restAuthenticationEntryPoint;
 @Bean
 public AuthenticationManager authenticationManagerBean() throws Exception {
 authenticationManagerBuilderreturn super.authenticationProviderauthenticationManagerBean(customAuthenticationProvider);
 }
 @Override
 protected void configure(HttpSecurityAuthenticationManagerBuilder httpauthenticationManagerBuilder) throws Exception {
 httpauthenticationManagerBuilder.userDetailsServiceauthenticationProvider(userDetailsServicenew CustomAuthenticationProvider());
 }
 http.addFilterBefore(new SimpleCORSFilter(), UsernamePasswordAuthenticationFilter.class);
 @Override
 protected void http.addFilterBeforeconfigure(authenticationFromTokenFilter,HttpSecurity UsernamePasswordAuthenticationFilter.classhttp);
 throws Exception {
 http.headers().cacheControlexceptionHandling();
 .authenticationEntryPoint(restAuthenticationEntryPoint)
 http.and()
 .csrf().disable().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
 .and().httpBasicaddFilterBefore()simpleCORSFilter, UsernamePasswordAuthenticationFilter.authenticationEntryPoint(restAuthenticationEntryPointclass)
 .andaddFilterBefore()authenticationFromTokenFilter, UsernamePasswordAuthenticationFilter.authorizeRequests(class)
 .antMatchers(RESTConstants.SLASH + RESTConstants.API + "/**".headers().hasRolecacheControl("ADMIN").anyRequestdisable().authenticatedframeOptions().disable()
 .antMatchersand(RESTConstants.SLASH)
 + RESTConstants.API + RESTConstants.SLASH + RESTConstants.ERRORuserDetailsService(userDetailsService).permitAllauthorizeRequests()
 .antMatchers(RESTConstants.SLASH + RESTConstantsUserDomainConstants.APIUSERS + RESTConstants.SLASH + UserDomainConstants.USERSLOGIN).permitAll()
 + .antMatchers(RESTConstants.SLASH + UserDomainConstantsRESTConstants.LOGINERROR).permitAll()
 .andantMatchers("/**").exceptionHandlinghasRole(UserDomainConstants.ROLE_ADMIN).authenticationEntryPointanyRequest(restAuthenticationEntryPoint).authenticated();
 }
}
@Component
public class CustomAuthenticationProvider implements AuthenticationProvider {
 @Autowired
 CredentialsService credentialsService;
 @Override
 public Authentication authenticate(Authentication authentication) throws AuthenticationException {
 String email = authentication.getName();
 String password = authentication.getCredentials().toString();
 List<SimpleGrantedAuthority> grantedAuthorities = new ArrayList<SimpleGrantedAuthority>();
 User user = null;
 try {
 user = credentialsService.findByEmail(new EmailAddress(email));
 } catch (IllegalArgumentException e) {
 throw new BadCredentialsException("The login " + email + " and password could not match."); 
 }
 if (user != null) {
 if (credentialsService.checkPassword(user, password)) {
 grantedAuthorities.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
 return new UsernamePasswordAuthenticationToken(email, password, grantedAuthorities);
 } else {
 throw new BadCredentialsException("The login " + user.getEmail() + " and password could not match."); 
 }
 }
 throw new BadCredentialsException("The login " + authentication.getPrincipal() + " and password could not match.");
 }
 @Override
 public boolean supports(Class<?> authentication) {
 return authentication.equals(UsernamePasswordAuthenticationToken.class);
 }
 @Bean
 public static NoOpPasswordEncoder passwordEncoder() {
 return (NoOpPasswordEncoder) NoOpPasswordEncoder.getInstance();
 }
}
@Component
public class AuthenticationFromTokenFilter extends GenericFilterBean {
 @Autowired
 private TokenAuthenticationService tokenAuthenticationService;
 @Override
 public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
 throws IOException, ServletException {
 HttpServletRequest httpRequest = getAsHttpRequest(request);
 tokenAuthenticationService.authenticateFromToken(httpRequest);
 chain.doFilter(request, response);
 }
 private HttpServletRequest getAsHttpRequest(ServletRequest request) {
 if (!(request instanceof HttpServletRequest)) {
 throw new RuntimeException("The request was not an HTTP request");
 }
 return (HttpServletRequest) request;
 }
}
@Service
public class TokenAuthenticationServiceImpl implements TokenAuthenticationService {
 private static Logger logger = LoggerFactory.getLogger(TokenAuthenticationServiceImpl.class);
 private static final long ONE_WEEK = 1000 * 60 * 60 * 24 * 7;
 private static final String TOKEN_URL_PARAM_NAME = "token";
 
 @Autowired
 private ApplicationProperties applicationProperties;
 @Autowired
 private UserDetailsService userDetailsService;
 public void addTokenToResponseHeader(HttpHeaders headers, String username) {
 String token = buildToken(username);
 headers.add(CommonConstants.AUTH_HEADER_NAME, token);
 }
 
 public void addTokenToResponseHeader(HttpServletResponse response, Authentication authentication) {
 String username = authentication.getName();
 if (username != null) {
 String token = buildToken(username);
 response.addHeader(CommonConstants.AUTH_HEADER_NAME, token);
 }
 }
 private String buildToken(String username) {
 String token = null;
 UserDetails userDetails = userDetailsService.loadUserByUsername(username);
 if (userDetails != null) {
 Date expirationDate = new Date(System.currentTimeMillis() + ONE_WEEK);
 token = CommonConstants.AUTH_BEARER + " " + Jwts.builder().signWith(HS256, getEncodedPrivateKey()).setExpiration(expirationDate).setSubject(userDetails.getUsername()).compact(); 
 }
 return token;
 }
 
 public Authentication authenticateFromToken(HttpServletRequest request) {
 String token = extractAuthTokenFromRequest(request);
 logger.debug("The request contained the JWT token: " + token);
 if (token != null && !token.isEmpty()) {
 try {
 String username = Jwts.parser().setSigningKey(getEncodedPrivateKey()).parseClaimsJws(token).getBody().getSubject();
 if (username != null) {
 UserDetails userDetails = userDetailsService.loadUserByUsername(username);
 UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
 authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
 SecurityContextHolder.getContext().setAuthentication(authentication);
 logger.debug("Security - The filter authenticated fine from the JWT token");
 }
 } catch (SignatureException e) {
 logger.info("The JWT token " + token + " could not be parsed.");
 }
 }
 return null;
 }
 private String extractAuthTokenFromRequest(HttpServletRequest request) {
 String token = null;
 String header = request.getHeader(CommonConstants.AUTH_HEADER_NAME);
 if (header != null && header.contains(CommonConstants.AUTH_BEARER)) {
 int start = (CommonConstants.AUTH_BEARER + " ").length();
 if (header.length() > start) {
 token = header.substring(start - 1);
 }
 } else {
 // The token may be set as an HTTP parameter in case the client could not set it as an HTTP header
 token = request.getParameter(TOKEN_URL_PARAM_NAME);
 }
 return token;
 }
 private String getEncodedPrivateKey() {
 String privateKey = applicationProperties.getAuthenticationTokenPrivateKey();
 return Base64.getEncoder().encodeToString(privateKey.getBytes());
 }
 
}
@Configuration
@EnableWebSecurity
@ComponentScan(nameGenerator = PackageBeanNameGenerator.class, basePackages = { "com.thalasoft.user.rest.security" })
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
 @Override
 protected void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
 authenticationManagerBuilder.authenticationProvider(customAuthenticationProvider);
 }
 @Override
 protected void configure(HttpSecurity http) throws Exception {
 http.userDetailsService(userDetailsService);
 http.addFilterBefore(new SimpleCORSFilter(), UsernamePasswordAuthenticationFilter.class);
 http.addFilterBefore(authenticationFromTokenFilter, UsernamePasswordAuthenticationFilter.class);

 http.headers().cacheControl();
 
 http
 .csrf().disable().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
 .and().httpBasic().authenticationEntryPoint(restAuthenticationEntryPoint)
 .and().authorizeRequests()
 .antMatchers(RESTConstants.SLASH + RESTConstants.API + "/**").hasRole("ADMIN").anyRequest().authenticated()
 .antMatchers(RESTConstants.SLASH + RESTConstants.API + RESTConstants.SLASH + RESTConstants.ERROR).permitAll()
 .antMatchers(RESTConstants.SLASH + RESTConstants.API + RESTConstants.SLASH + UserDomainConstants.USERS + RESTConstants.SLASH + UserDomainConstants.LOGIN).permitAll()
 .and().exceptionHandling().authenticationEntryPoint(restAuthenticationEntryPoint);
 }
}
@Component
public class CustomAuthenticationProvider implements AuthenticationProvider {
 @Autowired
 CredentialsService credentialsService;
 @Override
 public Authentication authenticate(Authentication authentication) throws AuthenticationException {
 String email = authentication.getName();
 String password = authentication.getCredentials().toString();
 List<SimpleGrantedAuthority> grantedAuthorities = new ArrayList<SimpleGrantedAuthority>();
 User user = null;
 try {
 user = credentialsService.findByEmail(new EmailAddress(email));
 } catch (IllegalArgumentException e) {
 throw new BadCredentialsException("The login " + email + " and password could not match."); 
 }
 if (user != null) {
 if (credentialsService.checkPassword(user, password)) {
 grantedAuthorities.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
 return new UsernamePasswordAuthenticationToken(email, password, grantedAuthorities);
 } else {
 throw new BadCredentialsException("The login " + user.getEmail() + " and password could not match."); 
 }
 }
 throw new BadCredentialsException("The login " + authentication.getPrincipal() + " and password could not match.");
 }
 @Override
 public boolean supports(Class<?> authentication) {
 return authentication.equals(UsernamePasswordAuthenticationToken.class);
 }
}
@Component
public class AuthenticationFromTokenFilter extends OncePerRequestFilter {
 @Autowired
 private TokenAuthenticationService tokenAuthenticationService;
 @Override
 protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
 throws IOException, ServletException {
 tokenAuthenticationService.authenticateFromToken(request);
 chain.doFilter(request, response);
 }
}
@Service
public class TokenAuthenticationServiceImpl implements TokenAuthenticationService {
 private static Logger logger = LoggerFactory.getLogger(TokenAuthenticationServiceImpl.class);
 private static final long ONE_WEEK = 1000 * 60 * 60 * 24 * 7;
 private static final String TOKEN_URL_PARAM_NAME = "token";
 
 @Autowired
 private ApplicationProperties applicationProperties;
 @Autowired
 private UserDetailsService userDetailsService;
 public void addTokenToResponseHeader(HttpHeaders headers, String username) {
 String token = buildToken(username);
 headers.add(CommonConstants.AUTH_HEADER_NAME, token);
 }
 
 public void addTokenToResponseHeader(HttpServletResponse response, Authentication authentication) {
 String username = authentication.getName();
 if (username != null) {
 String token = buildToken(username);
 response.addHeader(CommonConstants.AUTH_HEADER_NAME, token);
 }
 }
 private String buildToken(String username) {
 String token = null;
 UserDetails userDetails = userDetailsService.loadUserByUsername(username);
 if (userDetails != null) {
 Date expirationDate = new Date(System.currentTimeMillis() + ONE_WEEK);
 token = CommonConstants.AUTH_BEARER + " " + Jwts.builder().signWith(HS256, getEncodedPrivateKey()).setExpiration(expirationDate).setSubject(userDetails.getUsername()).compact(); 
 }
 return token;
 }
 
 public Authentication authenticateFromToken(HttpServletRequest request) {
 String token = extractAuthTokenFromRequest(request);
 logger.debug("The request contained the JWT token: " + token);
 if (token != null && !token.isEmpty()) {
 try {
 String username = Jwts.parser().setSigningKey(getEncodedPrivateKey()).parseClaimsJws(token).getBody().getSubject();
 if (username != null) {
 UserDetails userDetails = userDetailsService.loadUserByUsername(username);
 UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
 authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
 SecurityContextHolder.getContext().setAuthentication(authentication);
 logger.debug("Security - The filter authenticated fine from the JWT token");
 }
 } catch (SignatureException e) {
 logger.info("The JWT token " + token + " could not be parsed.");
 }
 }
 return null;
 }
 private String extractAuthTokenFromRequest(HttpServletRequest request) {
 String token = null;
 String header = request.getHeader(CommonConstants.AUTH_HEADER_NAME);
 if (header != null && header.contains(CommonConstants.AUTH_BEARER)) {
 int start = (CommonConstants.AUTH_BEARER + " ").length();
 if (header.length() > start) {
 token = header.substring(start - 1);
 }
 } else {
 // The token may be set as an HTTP parameter in case the client could not set it as an HTTP header
 token = request.getParameter(TOKEN_URL_PARAM_NAME);
 }
 return token;
 }
 private String getEncodedPrivateKey() {
 String privateKey = applicationProperties.getAuthenticationTokenPrivateKey();
 return Base64.getEncoder().encodeToString(privateKey.getBytes());
 }
 
}
@Configuration
@EnableWebSecurity
@ComponentScan(nameGenerator = PackageBeanNameGenerator.class, basePackages = { "com.thalasoft.user.rest.security", "com.thalasoft.user.rest.filter" })
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
 @Autowired
 private UserDetailsService userDetailsService;
  
 @Autowired
 private AuthenticationFromTokenFilter authenticationFromTokenFilter;
 
 @Autowired
 private SimpleCORSFilter simpleCORSFilter;
 
 @Autowired
 private RESTAuthenticationEntryPoint restAuthenticationEntryPoint;
 @Bean
 public AuthenticationManager authenticationManagerBean() throws Exception {
 return super.authenticationManagerBean();
 }
 @Override
 protected void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
 authenticationManagerBuilder.authenticationProvider(new CustomAuthenticationProvider());
 }
 @Override
 protected void configure(HttpSecurity http) throws Exception {
 http.exceptionHandling()
 .authenticationEntryPoint(restAuthenticationEntryPoint)
 .and()
 .csrf().disable().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
 .and().addFilterBefore(simpleCORSFilter, UsernamePasswordAuthenticationFilter.class)
 .addFilterBefore(authenticationFromTokenFilter, UsernamePasswordAuthenticationFilter.class)
 .headers().cacheControl().disable().frameOptions().disable()
 .and()
 .userDetailsService(userDetailsService).authorizeRequests()
 .antMatchers(RESTConstants.SLASH + UserDomainConstants.USERS + RESTConstants.SLASH + UserDomainConstants.LOGIN).permitAll()
 .antMatchers(RESTConstants.SLASH + RESTConstants.ERROR).permitAll()
 .antMatchers("/**").hasRole(UserDomainConstants.ROLE_ADMIN).anyRequest().authenticated();
 }
}
Notice added Draw attention by Stephane
Bounty Started worth 50 reputation by Stephane
added 229 characters in body
Source Link
Stephane
  • 12.9k
  • 28
  • 127
  • 188

I also tried to have the filter after as in:

http.addFilterAfter(authenticationFromTokenFilter, UsernamePasswordAuthenticationFilter.class);

instead of addFilterBefore but it didn't change anything to the issue.

I also tried to have the filter after as in:

http.addFilterAfter(authenticationFromTokenFilter, UsernamePasswordAuthenticationFilter.class);

instead of addFilterBefore but it didn't change anything to the issue.

added 358 characters in body
Source Link
Stephane
  • 12.9k
  • 28
  • 127
  • 188

So, is there anything wrong with my usage of the configure method for setting up the authenticationManagerBuilder.authenticationProvider(customAuthenticationProvider); ? Instead of the above configuration, I tried the following configuration:

@Autowired
public void initialize(AuthenticationManagerBuilder authenticationManagerBuilder) {
 authenticationManagerBuilder.authenticationProvider(customAuthenticationProvider);
}

But it still didn't exercise the custom authentication provider upon a request.

So, is there anything wrong with my usage of the configure method for setting up the authenticationManagerBuilder.authenticationProvider(customAuthenticationProvider); ?

So, is there anything wrong with my usage of the configure method for setting up the authenticationManagerBuilder.authenticationProvider(customAuthenticationProvider); ? Instead of the above configuration, I tried the following configuration:

@Autowired
public void initialize(AuthenticationManagerBuilder authenticationManagerBuilder) {
 authenticationManagerBuilder.authenticationProvider(customAuthenticationProvider);
}

But it still didn't exercise the custom authentication provider upon a request.

added 874 characters in body
Source Link
Stephane
  • 12.9k
  • 28
  • 127
  • 188
Loading
added 116 characters in body
Source Link
Stephane
  • 12.9k
  • 28
  • 127
  • 188
Loading
Source Link
Stephane
  • 12.9k
  • 28
  • 127
  • 188
Loading

AltStyle によって変換されたページ (->オリジナル) /