Интеграция единого входа с использованием Spring Безопасность
Я использую Spring Security, и я хотел бы использовать другой сайт в качестве одного из моих провайдеров проверки подлинности. У меня есть базовый логин на моем сайте. Я хочу иметь ссылку на моем сайте, которая приведет пользователя к внешнему сайту, на котором они будут входить в систему, и что внешний сайт затем отправит ответ xml мне со своими данными, которые я могу проверить, чтобы проверить, был ли успешный вход в систему. Любая помощь будет принята с благодарностью!
- Как вы интегрируете этот поток в Spring Безопасность?
- Как только я получу ответ, как я буду автоматически регистрировать пользователя?
используя приведенные ниже рекомендации:
фильтр (не показано, что мои данные поступают из 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;
}
}
Поставщик авторизации:
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 config:
<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
Общий подход:
1) Подкласс AbstractAuthenticationToken для ваших логинов XML, позвольте ему назвать XMLAuthenticationToken.
2) Подкласс AbstractAuthenticationProcessingFilter и добавьте его в цепочку фильтров после UsernamePasswordAuthenticationFilter. Он должен создать XMLAuthenticationToken на основе данных в XML. Вы можете использовать UsernamePasswordAuthenticationFilter в качестве примера для общей структуры фильтра (который, скорее всего, фильтр, который вы используете в настоящее время для ваших обычных логинов безопасности Spring).
<http>
<custom-filter after="FORM_LOGIN_FILTER" ref="xmlAuthenticationFilter"/>
</http>
Фильтр должен установить filterProcessesUrl, отличный от UserPasswordFilter. Это 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, у него есть хороший механизм расширения деталей) и DaoAuthenticationProvider (или подклассификация) для # 3.