0

I have two different types of users.

  1. SSO users
  2. DB users.

SSO users would have already been authenticated by different system and DB users should be authenticated by our system. Can i configure Spring security to handle this scenario where by i can say prompt login page for some users and don't prompt for some.

Lets say for SSO users i can get there users ID in request headers while DB when they access the application there is no user id present in request header .How can i handle this scenario ?

Can i override authenticate method of DaoAuthenticationProvider by extending it and then page on some parameter decide to authenticate user or is there any other means ? can i add any information to Authentication class

This is What i have tried to Far

Security Config java

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    DataSource dataSource;


    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder builder) throws Exception {
        builder.jdbcAuthentication().dataSource(dataSource).passwordEncoder(passwordEncoder())
                .usersByUsernameQuery("select username,password, enabled from users where username=?")
                .authoritiesByUsernameQuery("select username, role from user_roles where username=?");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().anyRequest().authenticated().and().httpBasic()
        .and().addFilterBefore(new UserTypeFilter(), BasicAuthenticationFilter.class);
    }

    public PasswordEncoder passwordEncoder() {
        PasswordEncoder encoder = new BCryptPasswordEncoder();
        return encoder;
    }

    /*
     * @Bean public MethodSecurityInterceptor methodSecurityService() { return
     * new MethodSecurityInterceptor(); }
     */

     @Bean(name="myAuthenticationManager")
       public AuthenticationManager authenticationManagerBean() throws Exception {
           return super.authenticationManagerBean();
       }

     @Bean
        public ExceptionTranslationFilter exceptionTranslationFilter() {
            ExceptionTranslationFilter exceptionTranslationFilter = new ExceptionTranslationFilter(
                    new Http403ForbiddenEntryPoint());
            AccessDeniedHandlerImpl accessDeniedHandlerImpl = new AccessDeniedHandlerImpl();
            accessDeniedHandlerImpl.setErrorPage("/exception");
            exceptionTranslationFilter
                    .setAccessDeniedHandler(accessDeniedHandlerImpl);
            exceptionTranslationFilter.afterPropertiesSet();
            return exceptionTranslationFilter;
        }

     @Bean
     public UserTypeFilter authenticationFilter() throws Exception {
         UserTypeFilter authFilter = new UserTypeFilter();
         authFilter.setAuthenticationManager(authenticationManager());
         return authFilter;
     }
}

My Custom AbstractAuthenticationProcessingFilter

public class UserTypeFilter extends AbstractAuthenticationProcessingFilter {

    private static final String INTERCEPTOR_PROCESS_URL = "/index";

    @Autowired
    public void setAuthenticationManager(AuthenticationManager authenticationManager) {
        super.setAuthenticationManager(authenticationManager);
    }

    public UserTypeFilter() {
        super(INTERCEPTOR_PROCESS_URL);
    }

    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
            throws AuthenticationException, IOException, ServletException {
        System.out.println(" BASIC AUTHENTICATION FILTER");
        String userId = request.getHeader("USERID");
        if (userId == null) {
            System.out.println(" THROWING EXCEPTION FILTER");
            throw new PreAuthenticatedCredentialsNotFoundException("USERID param not found");
        }
        return null;
    }

}

My Controller

@Controller
public class MainController {


    @RequestMapping(value = { "/index" }, method = RequestMethod.GET)
    public ModelAndView index() {

        ModelAndView model = new ModelAndView();
        model.addObject("message", "This is test page!");
        model.setViewName("dummy");

        return model;

    }

}

The control goes to My Custom filter and then when the exception is thrown but ExceptionTranslationFilter is not getting called

Have i configured httpsecurity correctly Have i configured My custom filter correctly Have i configured ExceptionTranslation Filter Am i missing anything

3
  • Did u think of adding filters in springsecurityfilterchain? Commented Dec 14, 2015 at 16:34
  • So there is a userId in the request headers. Is there any password or do you consider the request valid as long as the userId references a user that exists? How do you determine if the userId supplied in the request headers is a valid userId? Commented Dec 22, 2015 at 17:16
  • No Exactly i will validate that user id in DB if he exists or not . If the userid exists then he will be redirected to home page else to invalid user page. If user id is not present in request header then we will redirect to login page Commented Dec 24, 2015 at 7:00

1 Answer 1

2

This is a pretty standard use case for spring security. You will need to provide an Authentication object into the security context before any security interceptor is encountered.

Typically you would have some kind of filter which extracted SSO parameters from the request, authenticated those parameters against the SSO service, and then create an Authentication object and put it into the security context. The type of filter and configuration of the filter will depend on what SSO technology you are using.

There would often also be a filter (usually an ExceptionTranslationFilter) which will send unauthenticated requests to a login page.

There would also be filters to receive the parameters from the login form and store them in the security context.

Putting it all together I would expect one possible workflow to be:

User logs in with SSO parameters

  1. Request comes in prepopulated with credentials
  2. Some filter extracts those credentials, verifies them, creates an Authentication object, places the object in the security context.
  3. The security interceptor finds the Authentication object in the security context, verifies the user is allowed access to the particular function, and passes the request on.

User logs in without SSO parameters (needs login page)

  1. Request comes in with no credentials
  2. The security interceptor finds no Authentication object and throws an exception.
  3. The ExceptionTranslationFilter turns the exception into a redirect to a login page.

User logs in with filled out login form (e.g. for DB login)

  1. Request comes in with a login form as the entity body
  2. Some filter (e.g. UsernamePasswordAuthenticationFilter) extracts the credentials from the login form and defers to an authentication provider (e.g. your DAO authentication provider) to query the database and verify the user. If verified this filter will create an Authentication object and place it in the security context.
  3. The security interceptor finds the Authentication object in the security context, verifies the user is allowed access to the particular function, and passes the request on.
Sign up to request clarification or add additional context in comments.

3 Comments

I am trying to realize this by code what kind of filter should i write a Pre Auth Filter , should i through exception from Pre Auth Filter . How will the exception translation filter chain be called . Can you please guide me on this
If the data is in the request header then you don't have to wait for exception, you can check if the data is there and if it is, use it. I would extend AbstractAuthenticationProcessingFilter and use UsernamePasswordAuthenticationFilter as an example to work from.
i have updated my question with whatever i have tried so far can you have a look at it

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.