0

I am trying to implement URL authentication before it giving the response through business logic. For that I am using the authentication provider from Spring Security and trying to do one simple demo for testing authenticationProvider working properly. After this I am going to modify by adding my business logic.

My security config file SecurityConfig.java like the following,

@EnableWebSecurity
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

@Autowired
private CustomAuthenticationProvider authenticationProvider;

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

And My CustomAuthenticationProvider.java implementation like the following,

@Component
public class CustomAuthenticationProvider  implements AuthenticationProvider 
{
@SuppressWarnings("unused")
@Override
public Authentication authenticate(Authentication authToken) throws AuthenticationException {

    String userToken = (String) authToken.getName();
    String responseString = "test";
    String password = "test";

    if(responseString.equals(userToken)) {
        UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(userToken, password);
    return auth;
    }
    else {
        return null;
    }
}

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

And my TestSecurity.java like the following,

@RestController
public class TestSecurity {

 @GetMapping("/security/load")
 public String LoadSecureUsers() {

        return "hello spring security";
    }
}

When I am calling the URL localhost:8585/security/load with headers authToken: "test" from POSTMAN application, I am getting the following,

{
"timestamp": "2019-10-30T07:24:25.165+0000",
"status": 401,
"error": "Unauthorized",
"message": "Unauthorized",
"path": "/security/load"
}

If the condition are satisfying in IF, then how the URL is not able to access? Did I make any mistake in authentication Provider implementation?

1
  • You enabled basic authentication so you should be sending a proper authentication header. The fact that you do something in your custom authentication provider doesn't stop basic authentication from working. (Which in turn will call your authentication provider). Next to that it will still fail as you aren't assigning any authorities to the user the authenticated flag will remain false in the UsernamePasswordAuthenticationToken. Why bother with your custom provider? Just use the in-memory database and configure a user in that. Commented Oct 30, 2019 at 8:04

1 Answer 1

1

Instead of AuthenticationProvider use filter to process the request. This code might help you:

public class ApplicationAuthFilter extends BasicAuthenticationFilter {

    public ApplicationAuthFilter(AuthenticationManager authenticationManager) {
        super(authenticationManager);
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws IOException, ServletException {
        UsernamePasswordAuthenticationToken authentication = getAuthentication(request);
        SecurityContextHolder.getContext().setAuthentication(authentication);
        filterChain.doFilter(request, response);
    }

    private UsernamePasswordAuthenticationToken getAuthentication(HttpServletRequest request) {
        String token = String bearerToken = req.getHeader("accessToken");
    String username = "test";
    String password = "test"
        if (username != null && !username.isEmpty()) {
            return new UsernamePasswordAuthenticationToken(username, null, authorities);
        }
        return null;
    }
}

And your security config file like this:

@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
        .csrf().disable()
        .authorizeRequests()
        .anyRequest().authenticated()
        .and()
        .addFilter(new ApplicationAuthFilter(authenticationManager()))
    }

}

Basically you need to read the header information which you are passing with request and based on that you have to take action.

Hope this helps.

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you for your response. So I can not read autToken from request header by using authenticationProvider method ?
No you can not I guess because it is in request object, if you are passing information from header then you have to read it from header only. If this solves the problem accept the answer then :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.