Интеграция единого входа с использованием Spring Security - PullRequest
16 голосов
/ 20 марта 2011

Я использую Spring Security и хотел бы использовать другой сайт в качестве одного из моих провайдеров аутентификации.У меня есть базовая форма входа в систему на моем сайте.Я хочу, чтобы на моем сайте была ссылка, которая переводит пользователя на внешний сайт, где они будут входить в систему, и этот внешний сайт затем отправит мне ответ xml с данными, которые я смогу проверить, чтобы проверить, был ли успешный вход в систему.Любая помощь будет принята с благодарностью!

  1. Как интегрировать этот поток в Spring Security?
  2. Как только я получу ответ, как я могу автоматически войти в систему?

пример, используя приведенные ниже рекомендации:

фильтр (не показано, мои данные поступают из xml от запроса):

public class XMLAuthenticationFilter extends AbstractAuthenticationProcessingFilter{

    public XMLAuthenticationFilter() {
        super("/xml_security_check");
    }

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request,
            HttpServletResponse response) throws AuthenticationException,
            IOException, ServletException {

            GrantedAuthority[] grantedAuthorities = new GrantedAuthority[] { new GrantedAuthorityImpl("ROLE_USER")};
            UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("userid", "pwd", grantedAuthorities);
            request.getSession();
            token.setDetails(new WebAuthenticationDetails(request));
            Authentication authenticatedUser = super.getAuthenticationManager().authenticate(token);
            SecurityContextHolder.getContext().setAuthentication(authenticatedUser);
            request.getSession().setAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, SecurityContextHolder.getContext());
            return authenticatedUser;

}

}

AuthПоставщик:

public class XMLAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider{
    private UserManager userManager;
    @Override
    protected void additionalAuthenticationChecks(UserDetails user, UsernamePasswordAuthenticationToken token) throws AuthenticationException {

    }

    @Override
    protected UserDetails retrieveUser(String userName, UsernamePasswordAuthenticationToken token) throws AuthenticationException {
        UserDetails user = userManager.getUser(userName); 
        if(user == null){
            Users newDCUser = new Users();
            newDCUser.setUserId(userName);
            newDCUser.setRawPassword((String) token.getCredentials());
            newDCUser.setFailedLoginAttempts(0);
            newDCUser.setBeginEffectiveDate(new Date());
            newDCUser.setEndEffectiveDate(getEffectiveDate());
            userManager.saveUser(newDCUser);
        }
        return userManager.loadUserByUsername(userName);
    }

    private Date getEffectiveDate(){
         Calendar calendar = Calendar.getInstance();
         calendar.add(Calendar.YEAR, 10);
         return calendar.getTime();
    }

    public UserManager getUserManager() {
        return userManager;
    }

    public void setUserManager(UserManager userManager) {
        this.userManager = userManager;
    }
}

Конфигурация компонента:

<bean id="xmlAuthenticationFilter" class="com.dc.api.service.impl.XMLAuthenticationFilter">
        <property name="authenticationManager" ref="am" />
    </bean>
    <bean id="xmlAuthenticationProvider" class="com.dc.api.service.impl.XMLAuthenticationProvider">
        <property name="userManager" ref="userManager"/>
    </bean>

1 Ответ

8 голосов
/ 20 марта 2011

Общий подход:

1) Подкласс AbstractAuthenticationToken для ваших имен входа XML, назовем его XMLAuthenticationToken.

2) Подкласс AbstractAuthenticationProcessingFilter и добавьте его в цепочку фильтров после UsernamePasswordAuthenticationFilter. Он должен создать XMLAuthenticationToken на основе данных в XML. Вы можете использовать UsernamePasswordAuthenticationFilter в качестве примера для общей структуры фильтра (это, скорее всего, фильтр, который вы используете в настоящее время для своих обычных входов в Spring Security).

<http>
  <custom-filter after="FORM_LOGIN_FILTER" ref="xmlAuthenticationFilter"/>
</http>

Фильтр должен установить filterProcessesUrl, который отличается от UsernamePasswordFilter. Это URL, по которому внешняя система будет публиковать XML. Например:

public XmlAuthenticationFilter() {
    super("/xml_security_check");
}

3) Подкласс AbstractUserDetailsAuthenticationProvider. Пусть он найдет пользователя в UserDetailsService на основе информации в токене, а затем подтвердит его подлинность. Используйте DaoAuthenticationProvider в качестве примера. Вам нужно будет зарегистрировать нового провайдера в AuthenticationManager.

<authentication-manager>
  <authentication-provider user-service-ref='myUserDetailsService'/>
  <authentication-provider ref="xmlAuthenticationProvider" />
</authentication-manager>

Возможно, вам удастся избежать повторного использования UsernamePasswordAuthenticationToken (для # 1 он имеет хороший механизм расширения «details») и DaoAuthenticationProvider (или его подклассов) для # 3.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...