Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom AuthenticationProvider is not called

I want to have a basic auth-protected REST app. I followed the general instructions from http://www.baeldung.com/spring-security-authentication-provider in order to get the security working.

I ended up creating my implementation of AuthenticationProvider, but it never gets called by Spring. All requests end up with an error:

{"timestamp":1460199213227,"status":401,"error":"Unauthorized","message":"Full authentication is required to access this resource","path":"/test"}

without the AuthenticationProvider ever doing anything.

The app is annotation-based and here are the relevant bits:

Security setup

@Configuration
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
public class ApplicationSecurity extends WebSecurityConfigurerAdapter {
    @Autowired
    CustomAuthenticationProvider authenticationProvider;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(authenticationProvider);
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http
                .csrf().disable()
                .authenticationProvider(authenticationProvider)
                .authorizeRequests()
                .anyRequest().authenticated().and().httpBasic();
    }
}

AuthenticationProvider

@Component
public class CustomAuthenticationProvider implements AuthenticationProvider {
    @Autowired
    private UserDAO userDAO;
    @Autowired
    private Authenticator authenticator;

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        // This never gets called, I checked with debugger
        String username = authentication.getName();
        String password = authentication.getCredentials().toString();

        User user = userDAO.findByUsername(username);
        User authenticatedUser = authenticator.authenticate(user, password);
        if (authenticatedUser == null){
            throw new RESTAuthenticationException("Auth failed");
        }

        List<GrantedAuthority> authorityList = new ArrayList<>();
        return new UsernamePasswordAuthenticationToken(user, authorityList);
    }

    @Override
    public boolean supports(Class<?> aClass) {
        return aClass.equals(UsernamePasswordAuthenticationToken.class);
    }
}

Controller

@RestController
public class UserController {
    @RequestMapping(value = "/test")
    public ResponseEntity test(@AuthenticationPrincipal User user) {
        return ResponseEntity.ok().body(user);
    }
}
like image 766
Martin Melka Avatar asked Apr 09 '16 11:04

Martin Melka


People also ask

What is AuthenticationProvider in Spring Security?

The Authentication Provider Spring Security provides a variety of options for performing authentication. These options follow a simple contract; an Authentication request is processed by an AuthenticationProvider, and a fully authenticated object with full credentials is returned.

What is Spring Security filter chain?

Spring Security maintains a filter chain internally where each of the filters has a particular responsibility and filters are added or removed from the configuration depending on which services are required. The ordering of the filters is important as there are dependencies between them.

How Spring Security internally works?

The Spring Security ArchitectureThere are multiple filters in spring security out of which one is the Authentication Filter, which initiates the process of authentication. Once the request passes through the authentication filter, the credentials of the user are stored in the Authentication object.

How Spring Security works in Spring boot?

The short answer: At its core, Spring Security is really just a bunch of servlet filters that help you add authentication and authorization to your web application. It also integrates well with frameworks like Spring Web MVC (or Spring Boot), as well as with standards like OAuth2 or SAML.


Video Answer


1 Answers

You receive a response with status code 401. This is the "unauthorized" http status code. It is probably caused by a missing/malformed Authorization header in your request.

You are using Http-Basic: it requires the following header in the request :

Authorization: Basic QWxhZGRpbjpPcGVuU2VzYW1l

where the string QWxhZGRpbjpPcGVuU2VzYW1l is the string <user>:<password> base64 encoded.

like image 175
ben75 Avatar answered Oct 16 '22 14:10

ben75