如何通过弹簧安全login页面传递附加参数

我试图从弹簧安全login页面设置数据库名称作为请求input参数。 目前我只获取使用spring security SecurityContextHolder.getContext().getAuthentication()获取的用户名。

如何访问login页面上设置的附加字段?

在@ Vacuum上发表评论

这是一个简单的方法(未经testing,但我相信这将工作)

1)创build一个新类ExUsernamePasswordAuthenticationFilter,它将扩展默认的filter并获取附加参数并将其存储在会话中。 它看起来像这样:

  public class ExUsernamePasswordAuthenticationFilter extends UsernamePasswordAuthenticationFilter { @Override public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException { final String dbValue = request.getParameter("dbParam"); request.getSession().setAttribute("dbValue", dbValue); return super.attemptAuthentication(request, response); } } 

2)在你的UserDetailsS​​ervice实现中,修改你的实现:

 UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException; 

抓取步骤1)中的filter可用的会话variables。

3)在你的<http />安全设置中,用你自定义的filter覆盖默认的filter

 <custom-filter ref="beanForYourCustomFilterFromStep1" position="FORM_LOGIN_FILTER"/> 

有关自定义filter的更多信息,请参阅本文档的这一部分: http : //static.springsource.org/spring-security/site/docs/3.1.x/reference/springsecurity-single.html#ns-custom-filters

有很多方法可以做到这一点,但官方的方法是使用自定义的AuthenticationDetailsAuthenticationDetailsSource ,分别为Spring的WebAuthenticationDetailsWebAuthenticationDetailsSource 。 将额外的字段添加到自定义WebAuthenticationDetails并让自定义WebAuthenticationDetailsSource从请求中获取数据以填充该字段。

在Spring Security 3.1中,通过使用<form-login>元素的authentication-details-source-ref属性很容易configuration。

在3.0中,你必须使用一个BeanPostProcessor 。 在Spring Security FAQ中有一个使用BeanPostProcessor来configuration自定义WebAuthenticationDetailsS​​ource的例子 。

一旦完成,你可以调用SecurityContextHolder.getContext()。getAuthentication()。getDetails()来访问你的额外字段。

sourcedelica提到使用AuthenticationDetailsSource和一个自定义的AuthenticationDetails 。 这是一个例子。

使用bean id customWebAuthenticationDetailsSource添加authentication-details-source-ref属性到form-login

 <security:http> <security:intercept-url pattern="/**" access="..." /> <security:form-login authentication-details-source-ref="customWebAuthenticationDetailsSource" login-page="..." /> <security:logout logout-success-url="..." /> </security:http> 

创build一个新的类CustomWebAuthenticationDetailsSource

 package security; import org.springframework.security.authentication.AuthenticationDetailsSource; import org.springframework.security.web.authentication.WebAuthenticationDetails; import javax.servlet.http.HttpServletRequest; public class CustomWebAuthenticationDetailsSource implements AuthenticationDetailsSource<HttpServletRequest, WebAuthenticationDetails> { @Override public WebAuthenticationDetails buildDetails(HttpServletRequest context) { return new CustomWebAuthenticationDetails(context); } } 

和相关的CustomWebAuthenticationDetails

 package security; import org.springframework.security.web.authentication.WebAuthenticationDetails; import javax.servlet.http.HttpServletRequest; public class CustomWebAuthenticationDetails extends WebAuthenticationDetails { private final String yourParameter; public CustomWebAuthenticationDetails(HttpServletRequest request) { super(request); yourParameter = request.getParameter("yourParameter"); } public String getyourParameter() { return yourParameter; } //TODO override hashCode, equals and toString to include yourParameter @Override public int hashCode() { /* collapsed */ } @Override public boolean equals(Object obj) { /* collapsed */ } @Override public String toString() { /* collapsed */ } } 

@ user1322340不提供实现细节来获取loadUserByUsername函数中的session属性:

第1步:执行@ user1322340提供的所有步骤

第2步:您需要在web.xml中添加一个configuration,如下所示:

 <listener> <listener-class> org.springframework.web.context.request.RequestContextListener </listener-class> </listener> 

第3步:使用这样的代码来获取属性:

 RequestContextHolder.getRequestAttributes().getAttribute("yourAttributeName", RequestAttributes.SCOPE_SESSION); 

步骤4:在spring安全configuration中注册你的filter。 如果出现错误“ 必须指定authenticationManager ”。 在config中注册你的filter之后。 您需要为您的扩展filter设置一个authenticationManagerBean并以这种方式进行configuration:

 @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Bean public ExUsernamePasswordAuthenticationFilter exUsernamePasswordAuthenticationFilter() throws Exception { ExUsernamePasswordAuthenticationFilter exUsernamePasswordAuthenticationFilter = new ExUsernamePasswordAuthenticationFilter(); exUsernamePasswordAuthenticationFilter .setAuthenticationManager(authenticationManagerBean()); return exUsernamePasswordAuthenticationFilter; } @Bean @Override public AuthenticationManager authenticationManagerBean() throws Exception { return super.authenticationManagerBean(); } @Override protected void configure(HttpSecurity http) throws Exception { RequestMatcher requestMatcher = new RequestMatcher() { @Override public boolean matches(HttpServletRequest httpServletRequest) { if (httpServletRequest.getRequestURI().indexOf("/api", 0) >= 0) { return true; } return false; } }; http .addFilterBefore(exUsernamePasswordAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class) ... } } 

对于使用javaconfiguration的spring security 3.0或更高版本,以下简单步骤运行良好。

  • 在configuration中的HttpSecurity对象的UserNameandPasswordAuthenticationFilter之前添加你的filter。

     http.addFilterBefore(new YourFilter(), UsernamePasswordAuthenticationFilter.class); 
  • 让filter有这样的一行来获得请求会话中所需的字段。

     if(requestPath != null &&requestPath.equals("/login") ) { session.setAttribute("yourParam",req.getParameter("yourParam")); } 
  • 稍后,您可以从任何类中的会话中获取参数值,如下所示:

     String yourParam =(String)request.getSession().getAttribute("yourParam"); 

如果您使用自定义AuthenticationProvider则有一个更简单的方法。 您可以注入HttpServletRequest并检索您的额外参数:

 @Component public class CustomAuthenticationProvider implements AuthenticationProvider { @Autowired(required = false) private HttpServletRequest request; @Autowired private MyAccountService myAccountService; @Override public Authentication authenticate(Authentication authentication) { System.out.println("request testing= " + request.getParameter("testing")); ..... } @Override public boolean supports(Class<?> authentication) { return authentication.equals(UsernamePasswordAuthenticationToken.class); } } 

简单的方法:

1)注册RequestContextListener

 @Bean public RequestContextListener requestContextListener(){ return new RequestContextListener(); } 

2)主要课程:

 HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder. currentRequestAttributes()). getRequest(); 

3)之后,我们可以在自定义标题中使用参数:

 request.getHeader("OrganizationId")