关于多个authentication-manager的使用问题

首先是http的配置, authentication-manager-ref="authenticationManager"指定了默认的authentication-manager
<http auto-config="true" authentication-manager-ref="authenticationManager">
               ... ...
        <logout logout-url="/dynamic/j_spring_security_logout"
            logout-success-url="/login.html" invalidate-session="true" />

         <custom-filter before="REMEMBER_ME_FILTER" ref="tokenLoginFilter" />

</http>


下面是我的两个authentication-manager配置

    <authentication-manager id="authenticationManager">
        <authentication-provider user-service-ref="userDetailsServiceImpl">
            <!-- 用于密码的认证 -->
            <password-encoder ref="userPasswordEncoder" />
        </authentication-provider>
    </authentication-manager>
    
    <authentication-manager id="equalAuthenticationManager">
         <authentication-provider user-service-ref="userDetailsServiceImpl">
            <!--用于不需要密码的认证 -->
            <password-encoder ref="equalPasswordEncoder" />
        </authentication-provider>
    </authentication-manager>


好了,另一个equalAuthenticationManager在哪里被使用呢,就是tokenLoginFilter了。

下面是tokenLoginFilter的代码

package org.foggy.application.basic.impl.security;

import java.io.IOException;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.foggy.application.basic.impl.BasicRuntimeImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.security.authentication.AuthenticationDetailsSource;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.authentication.event.InteractiveAuthenticationSuccessEvent;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.GenericFilterBean;

@Component
public class TokenLoginFilter extends GenericFilterBean implements
		ApplicationEventPublisherAware {

	@Autowired
	BasicRuntimeImpl runtime;

	@Autowired
	@Qualifier("equalAuthenticationManager")
	AuthenticationManager authenticationManager;

	@Autowired
	UserDetailsService userDetailsService;

	AuthenticationDetailsSource authenticationDetailsSource = new WebAuthenticationDetailsSource();

	private ApplicationEventPublisher eventPublisher;

	@Override
	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {

		if (SecurityContextHolder.getContext().getAuthentication() != null) {
			chain.doFilter(request, response);
			return;
		}
		String tokenId = request.getParameter("tokenId");
		if (tokenId == null) {
			/**
			 * 没有tokenId,交由下一个Filter处理
			 */
			chain.doFilter(request, response);
			return;
		}
		Authentication auth = null;
		try {
			UserDetails ud = userDetailsService.loadUserByUsername(tokenId);
			if (ud == null) {
				throw new UsernameNotFoundException("tokenId : [" + tokenId
						+ "] not found");
			}
			UsernamePasswordAuthenticationToken upToken = new UsernamePasswordAuthenticationToken(
					ud, ud.getPassword(), ud.getAuthorities());

			upToken.setDetails(authenticationDetailsSource
					.buildDetails(request));

			/**
			 * 调用 authenticationManager的认证方法
			 */
			auth = authenticationManager.authenticate(upToken);
			/**
			 * 成功,设置当前上下文的认证信息
			 */
			SecurityContextHolder.getContext().setAuthentication(auth);
			
			onSuccessfulAuthentication((HttpServletRequest) request,
					(HttpServletResponse) response, auth);

			/**
			 * 发出InteractiveAuthenticationSuccessEvent事件
			 */
			if (eventPublisher != null) {
				eventPublisher
						.publishEvent(new InteractiveAuthenticationSuccessEvent(
								SecurityContextHolder.getContext()
										.getAuthentication(), this.getClass()));
			}
		} catch (AuthenticationException authenticationException) {
			if (logger.isDebugEnabled()) {
				logger.debug(
						"SecurityContextHolder not populated with remember-me token, as "
								+ "AuthenticationManager rejected Authentication returned by RememberMeServices: '"
								+ auth + "'; invalidating remember-me token",
						authenticationException);
			}

			onUnsuccessfulAuthentication((HttpServletRequest) request,
					(HttpServletResponse) response, authenticationException);
		}
		chain.doFilter(request, response);
	}

	protected void onSuccessfulAuthentication(HttpServletRequest request,
			HttpServletResponse response, Authentication authResult) {
	}

	protected void onUnsuccessfulAuthentication(HttpServletRequest request,
			HttpServletResponse response, AuthenticationException failed) {
	}

	@Override
	public void setApplicationEventPublisher(
			ApplicationEventPublisher eventPublisher) {
		this.eventPublisher = eventPublisher;
	}
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Spring Security中,可以使用多个authentication-provider来支持不同类型的身份验证。为了通过XML配置多个authentication-provider,需要按照以下步骤进行操作: 1. 在Spring Security配置文件中定义多个authentication-provider元素,并设置它们的属性和子元素,如下所示: ``` <authentication-manager> <authentication-provider user-service-ref="userDetailsService1" /> <authentication-provider user-service-ref="userDetailsService2" /> </authentication-manager> ``` 其中,user-service-ref属性指定要使用的UserDetailsService实现的bean名称。 2. 配置每个UserDetailsService bean,以便它将验证请求委托给适当的身份验证提供程序。例如,下面是一个UserDetailsService bean的示例: ``` <bean id="userDetailsService1" class="org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl"> <property name="dataSource" ref="dataSource1" /> <property name="usersByUsernameQuery" value="SELECT username,password,enabled FROM users WHERE username=?" /> <property name="authoritiesByUsernameQuery" value="SELECT username, authority FROM authorities WHERE username=?" /> </bean> ``` 3. 如果需要,可以配置每个authentication-provider的authentication-event-listener元素,以便在验证过程中捕获和处理特定事件。例如,下面是一个authentication-event-listener元素的示例: ``` <authentication-provider user-service-ref="userDetailsService1"> <authentication-event-listener ref="myAuthenticationListener" /> </authentication-provider> ``` 4. 最后,可以使用Spring Security的全局配置元素,如global-method-security和intercept-url,来定义更高级的安全控制。 总之,通过XML配置多个authentication-provider是通过配置多个authentication-provider元素,并将它们的属性和子元素与适当的UserDetailsService bean关联来实现的。这允许Spring Security支持多种身份验证方法,并为每种身份验证方法提供自定义配置和事件处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值