Spring安全自定义登录URL

时间:2016-01-20 08:02:06

标签: java spring spring-security

我有以下Sprring网络应用程序:

@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)

在登录时,我需要调用另一台服务器,传递凭据并获取角色,然后让spring知道将这些角色用于传入用户。 登录后,如果通过ROLE_ADMIN的授权,客户端可以使用getData方法。

如何使用java config实现此行为?

更新:

@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 {
}

但正如我从日志中看到的那样,从不调用CustomAuthenticationProvider.authenticate。 我错过了什么? 感谢。

更新2:为我提供正确的解决方案:

  1. 从身份验证配置中删除登录网址
  2. 添加异常处理程序以在发生身份验证错误时禁用重定向
  3. 添加成功处理程序以发送用户有效的json响应
  4. 使用http POST进行app / login
  5. Web配置中的
  6. @EnableGlobalMethodSecurity(securedEnabled = true),以便在控制器中允许@Secured注释。 感谢所有提示。
  7. @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)**;
    }
    

2 个答案:

答案 0 :(得分:3)

您需要像这样使用WebSecurityConfigurerAdapter:

@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");
}    
}

每件事都在文档https://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#jc-form

中解释

答案 1 :(得分:0)

您需要实现自定义AuthenticationProvider。类似的东西:

@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 */
}

}