Spring安全性:使用http basic和表单登录进行身份验证

时间:2016-06-23 09:21:57

标签: spring web-services authentication spring-security

我的身份验证存在巨大而奇怪的问题。我有两种类型的身份验证,一种是通过网页进行身份验证,一种是我的网络服务,但它不起作用。事实上,即使我不提供凭据,服务器也接受我的身份验证并继续进行。这是一个很大的问题,我不明白为什么,我想:

1)外部web服务是/ client / * URL,必须对这些服务进行身份验证。 POST / client / file不能进行身份验证。所有其他Web服务都没有提供服务,因此可能无法访问或使用身份验证。这是一次性身份验证,因为检查用户是否已启用并为其提供Web服务结果

2)内部Web服务似乎有效,都需要身份验证 我的配置有什么问题?

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true, proxyTargetClass = true)
@PropertySource(value = { "classpath:application.properties" })
public class SecurityConfig extends WebSecurityConfigurerAdapter {


    @Autowired
    AuthenticationConfiguration authenticationConfiguration;

    @Configuration
    protected static class AuthenticationConfiguration implements
    AuthenticationProvider {

        @Autowired
        private UserServices userServices;
        @Autowired
        LdapServices ldapServices;

        @Override
        public Authentication authenticate(Authentication authentication) throws AuthenticationException {
            Set<GrantedAuthority> authorities = new HashSet<GrantedAuthority>();
            String name = authentication.getName();
            String password = authentication.getCredentials().toString();
            boolean isFind = ldapServices.ldapSearch(name, password);                           
            if (isFind){
                com.domain.User user = userServices.getByUsersEnabled(name);
                if (user!=null)
                    authorities.add(new SimpleGrantedAuthority("ROLE_"+user.getRole().getRole()));          
                return new UsernamePasswordAuthenticationToken(name, password, authorities);
            }           
            else return null;
        }


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

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

    @Configuration
    @Order(1)
    public static class ApiWebSecurityConfig extends WebSecurityConfigurerAdapter{
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http
        .csrf().disable()
        .antMatcher("/client/**")
        .authorizeRequests()
        //Exclude send file from authentication because it doesn't work with spring authentication
        .antMatchers(HttpMethod.POST, "/client/file").permitAll()
        .anyRequest().authenticated()
        .and()
        .httpBasic();      
        }
    }

    @Configuration
    @Order(2)
    public static class FormWebSecurityConfig extends WebSecurityConfigurerAdapter{

        @Autowired
        RoleServices roleServices;

        @Override
        public void configure(WebSecurity web) throws Exception {
            web
            //Spring Security ignores request to static resources such as CSS or JS files.
            .ignoring()
            .antMatchers("/static/**");
        }

        @Override
        protected void configure(HttpSecurity http) throws Exception {         
            List<Role> roles=roleServices.getRoles();
            //Retrieve array of roles(only string field without id)
            String[] rolesArray = new String[roles.size()];
            int i=0;
            for (Role role:roles){
                rolesArray[i++] = role.getRole();
            }

            http
            .authorizeRequests() //Authorize Request Configuration
            .anyRequest().hasAnyRole(rolesArray)//.authenticated()
            .and() //Login Form configuration for all others
            .formLogin()
            .loginPage("/login")
            //important because otherwise it goes in a loop because login page require authentication and authentication require login page
            .permitAll()
            .and()
            //redirect on page 403 if user doens't exist in DART database
            .exceptionHandling().accessDeniedPage("/403")
            .and()
            .logout()
            .logoutSuccessUrl("/login?logout")
            .permitAll();

        }
    }
}

1 个答案:

答案 0 :(得分:0)

这是新代码,似乎有效:

@Configuration
@Order(1)
public static class ApiWebSecurityConfig extends WebSecurityConfigurerAdapter{
    @Autowired
    RoleServices roleServices;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        List<Role> roles = roleServices.getRoles();
        //Retrieve array of roles(only string field without id)
        String[] rolesArray = new String[roles.size()];
        int i=0;
        for (Role role:roles){
            rolesArray[i++] = role.getRole();
        }

        http
        .csrf().disable()
        .antMatcher("/client/**")
        .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
        .and()
        .authorizeRequests()
        //Exclude send file from authentication because it doesn't work with spring authentication
        .antMatchers(HttpMethod.POST, "/client/file").permitAll()
        .anyRequest().hasAnyRole(rolesArray)
        .and()
        .httpBasic();   
    }
}

.antMatcher("/client/**")捕获所有/client网址请求并使用httpBasic身份验证,.anyRequest().hasAnyRole(rolesArray)仅允许具有角色的用户进行身份验证。 .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)保证Spring Security不使用任何会话。不使用Cookie,因此需要重新验证每个请求。这种无状态架构适用于REST API及其无状态约束。