spring-attic / spring-social

Allows you to connect your applications with SaaS providers such as Facebook and Twitter.
http://projects.spring.io/spring-social
Apache License 2.0
619 stars 351 forks source link

SocialAuthenticationProvider doesn't check user status (locked, enabled, etc.) #231

Open xolvo opened 7 years ago

xolvo commented 7 years ago

Summary

SocialAuthenticationProvider must check if user locked, enabled, etc. if it was already signed up.

Actual Behavior

If user is locked and trying to login with social identity (Facebook for example) he actually can do it even if he was marked as locked by admin.

Expected Behavior

Locked users must not be able to login with social provider

Version

Spring Social 1.1.4.RELEASE

nhs3108 commented 7 years ago

I also got this issue few months ago. To resolve it, I create CustomSocialAuthenticationProvider extends SocialAuthenticationProvider and overide authenticate(Authentication authentication), use check(UserDetails user) look like this

private void check(UserDetails user) {
        if (!user.isAccountNonLocked()) {
            LOGGER.debug("User account is locked");

            throw new LockedException("User account is locked");
        }

        if (!user.isEnabled()) {
            LOGGER.debug("User account is disabled");

            // throw new DisabledException("User is disabled");
            // Force to sign up
            throw new BadCredentialsException("Unknown access token");
        }

        if (!user.isAccountNonExpired()) {
            LOGGER.debug("User account is expired");

            throw new AccountExpiredException("User account has expired");
        }
    }
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        Assert.isInstanceOf(SocialAuthenticationToken.class, authentication, "unsupported authentication type");
        Assert.isTrue(!authentication.isAuthenticated(), "already authenticated");
        SocialAuthenticationToken authToken = (SocialAuthenticationToken) authentication;
        String providerId = authToken.getProviderId();
        Connection<?> connection = authToken.getConnection();

        String userId = toUserId(connection);
        if (userId == null) {
            throw new BadCredentialsException("Unknown access token");
        }

        UserDetails userDetails = userDetailsService.loadUserByUserId(userId);
        if (userDetails == null) {
            throw new UsernameNotFoundException("Unknown connected account id");
        }
                check(userDetails);
        return new SocialAuthenticationToken(connection, userDetails, authToken.getProviderAccountData(), getAuthorities(providerId, userDetails));
    }
<beans:bean id="socialAuthenticationFilter"
                class="org.springframework.social.security.SocialAuthenticationFilter">
        <beans:constructor-arg index="0"
                               ref="authenticationManager"/>
        <beans:constructor-arg index="1" ref="userIdSource"/>
        <beans:constructor-arg index="2"
                               ref="usersConnectionRepository"/>
        <beans:constructor-arg index="3"
                               ref="connectionFactoryLocator"/>
        <!-- Sets the url of the registration form. -->
        <beans:property name="signupUrl" value="/signup"/>
        <beans:property name="authenticationSuccessHandler"
                        ref="loginSocialSuccessHandler"/>
        <beans:property name="authenticationFailureHandler"
                        ref="socialLoginFailureHandler"/>
        <beans:property name="rememberMeServices" ref="tokenBasedRememberMeServices"/>
    </beans:bean>
<authentication-manager alias="authenticationManager">
        <authentication-provider user-service-ref="customUserDetailsService">
            <password-encoder ref="passwordEncoder"></password-encoder>
        </authentication-provider>
        <authentication-provider ref="socialAuthenticationProvider"/>
    </authentication-manager>
<beans:bean id="socialAuthenticationProvider"
                class="com.package.name.config.security.CustomSocialAuthenticationProvider">
        <beans:constructor-arg index="0"
                               ref="usersConnectionRepository"/>
        <beans:constructor-arg index="1"
                               ref="socialUserDetailsService"/>
    </beans:bean>

I forgot sending pull-request to contribute :( I will do it soon. Hope repository's owners will approve

xolvo commented 7 years ago

I also have workaround for this issue. And yours is too difficult... This issue must be solved inside this library to prevent others from bugs in their systems.

@habuma please, take a look

ghost commented 3 years ago

Is there any news?