简体   繁体   中英

Spring security custom login url

I have the following Sprring web app:

@Secured({"ROLE_ADMIN"})
@RequestMapping(value = "data/{id}", method = RequestMethod.GET)
public Object getData(@RequestPath String id)

@RequestMapping(value = "login", method = RequestMethod.GET)
public Object login(@RequestParam String username, @RequestParam String password)

In login I need to call another server, pass credentials and get back roles, then let spring know to use these roles for incoming user. After login client can use getData method if pass authorization of ROLE_ADMIN.

How can I implement this behaviour using java config?

UPDATE:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    public AuthenticationProvider authenticationProvider;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .antMatchers("/login").permitAll()
                .anyRequest().authenticated()
            ;
    }


    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(authenticationProvider);
    }
}

@Component
public class CustomAuthenticationProvider implements AuthenticationProvider {

    private static final Logger logger = LogFactory.getLogger();

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        String name = authentication.getName();
        String password = authentication.getCredentials().toString();
        log.debug("name=" + name + " password=" + password);
        List<GrantedAuthority> grantedAuths = new ArrayList<>();
        grantedAuths.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
        Authentication auth = new UsernamePasswordAuthenticationToken(name, password, grantedAuths);
        return auth;
    }

    @Override
    public boolean supports(Class<?> authentication) {
        logger.debug("supports authentication=" + authentication);
        return true;
    }
}

public class SecurityInitializer extends AbstractSecurityWebApplicationInitializer {
}

But as I can see from the logs CustomAuthenticationProvider.authenticate is never called. Did I miss something? Thanks.

UPDATE 2: correct solution for me:

  1. Remove Login url from authentication config
  2. add exception handler to disable redirection in case of authentication error
  3. add success handler to send user valid json response
  4. use http POST for app/login
  5. @EnableGlobalMethodSecurity(securedEnabled = true) in web config in order to allow @Secured annotation in controller. Thanks for all prompts.

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests()
    **.anyRequest().authenticated()**
    .and().formLogin()
    .loginProcessingUrl("/login").usernameParameter("username")
    .passwordParameter("password")
    **.successHandler(authenticationSuccessHandler)**.failureHandler(authenticationFailureHandler)
    .and().csrf().disable().**exceptionHandling()
    .authenticationEntryPoint(errorsAuthenticationEntryPoint)**;
}

You need to use WebSecurityConfigurerAdapter like this:

@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
        .logout()
            .logoutUrl("/myurl/logout")
            .and()
        .formLogin()
            .loginPage("/myurl/login")
            .defaultSuccessUrl("/myurl/login?success");
}    
}

Every thing is explain in the documentation https://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#jc-form

You will need to implement a custom AuthenticationProvider. Something like:

@Configuration
@EnableWebMvcSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

@Autowired
public void registerGlobalAuthentication(AuthenticationManagerBuilder auth) throws Exception {
    auth.authenticationProvider(customAuthenticationProvider());
}

@Bean
AuthenticationProvider customAuthenticationProvider() {
    CustomAuthenticationProvider impl = new CustomAuthenticationProvider();
    impl.setUserDetailsService(customUserDetailsService());
    /* other properties etc */
    return impl ;
}

@Bean   
UserDetailsService customUserDetailsService() {
    /* custom UserDetailsService code here */
}

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM