Reputation: 782
I wanted to allow HAL browser to skip authorization on a spring boot application. I am using Spring Security for authorization.
Here is the snap shot of the entries from build.gradle file
implementation 'org.springframework.boot:spring-boot-starter-data-rest'
implementation 'org.springframework.boot:spring-boot-starter-hateoas'
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation 'org.springframework.boot:spring-boot-starter-security'
My Spring boot application runs on port 2128
http://localhost:2128/browser/index.html would open the HAL browser before spring security was implemented. I tried adding .antMatchers("/browser/index.html").permitAll()** in the configure method of SecurityConfiguration class given below. I also tried overriding public void configure(WebSecurity web) method to ignore the URL
Background : HAL Browser was working before I have implemented Spring Security Authorization. It stopped working after spring security was implemented.
@Configuration @EnableWebSecurity public class SecurityConfiguration extends WebSecurityConfigurerAdapter { @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.authenticationProvider(daoAuthenticationProvider()); } @Override protected void configure(HttpSecurity http) throws Exception { http .csrf().disable() .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) .and() .addFilter(new AuthorizationFilter(authenticationManager(), userRepository)) .authorizeRequests() // configure access rules .antMatchers("/browser/index.html**").permitAll() .anyRequest().authenticated(); http.headers().frameOptions().disable(); } @Override public void configure(WebSecurity web) throws Exception { web.ignoring().antMatchers("/browser/index.html"); } }
public class AuthorizationFilter extends BasicAuthenticationFilter { public static final String HEADER_STRING_REMOTE_USER = "Remote-User"; /** * Security pipe line is composed of different filters so we need to delegate to the rest of the pipeline. * * @param request * @param response * @param chain * @throws IOException * @throws ServletException */ @Override protected void doFilterInternal (HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException { // Read the Authorization header, where we get the userId String userId = request.getHeader(HEADER_STRING_REMOTE_USER); // If header does not contain userId or is null delegate to Spring impl and exit if (userId == null) { chain.doFilter(request, response); return; } // If userId is present, try grab user principal from database and perform authorization Authentication authentication = getUsernamePasswordAuthentication(userId); SecurityContextHolder.getContext().setAuthentication(authentication); // Continue filter execution chain.doFilter(request, response); } private Authentication getUsernamePasswordAuthentication (String userId) { // Search in the DB if we find the user by userId // If so, then grab user details and create spring auth token using username, pass, authorities/roles if (userId != null) { List user = userRepository.findByUserId(userId); UserPrincipal principal = new UserPrincipal(user.get(0)); UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(principal, null, principal.getAuthorities()); return auth; } return null; } }
Has anybody experienced similar issues...
Upvotes: 3
Views: 1571
Reputation: 782
What I ended up doing is to manage using spring active profiles.
For more information on spring profiles see the link
I enabled Spring Security for "secure" profile and disabled it for "dev" profile. So in "dev" profile HAL browser works without any security interruptions.
@Configuration
@EnableWebSecurity
@Profile("secure")
public class WebSecurityConfigEnable extends WebSecurityConfigurerAdapter {
@Autowired
UserPrincipalDetailsService userPrincipalDetailsService;
private UserRepository userRepository;
@Value("${spring.profiles.active}")
private String activeProfile;
public WebSecurityConfigEnable (UserPrincipalDetailsService
userPrincipalDetailsService, UserRepository userRepository) {
this.userPrincipalDetailsService = userPrincipalDetailsService;
this.userRepository = userRepository;
}
@Override
protected void configure (AuthenticationManagerBuilder auth) throws
Exception {
auth.authenticationProvider(daoAuthenticationProvider());
}
@Override
protected void configure (HttpSecurity http) throws Exception {
http
.cors().configurationSource(request -> new
CorsConfiguration().applyPermitDefaultValues())
.and()
.csrf().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.addFilter(new AuthorizationFilter(authenticationManager(),
userRepository, activeProfile))
.authorizeRequests()
// configure access rules
.anyRequest().authenticated();
}
@Bean
DaoAuthenticationProvider daoAuthenticationProvider () {
DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
daoAuthenticationProvider.setPasswordEncoder(this.passwordEncoder());
daoAuthenticationProvider.setUserDetailsService(this.userPrincipalDetailsService);
return daoAuthenticationProvider;
}
@Bean
PasswordEncoder passwordEncoder () {
return new BCryptPasswordEncoder();
}
}
For running the application in "dev" profile
java -jar -Dspring.profiles.active=dev build\libs\springApp-0.1.1-SNAPSHOT.jar
Upvotes: 2