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...
.antMatchers("/browser/**").permitAll()?. There are more resources needed besides the index.html (js, css, images). Of course, for your api calls you will need auth, so you either need to have a session cookie, or you can specify the Authorization header in hal-explorer if you use it. PS: if you are using the new hal-explorer instead of hal-browser, use.antMatchers("/explorer/**").permitAll()- Dan Manastireanu