我正在尝试将数据库名称设置为来自 spring 安全登录页面的请求输入参数。目前我只得到使用 spring security 检索到的用户名SecurityContextHolder.getContext().getAuthentication()
。
如何访问登录页面上设置的附加字段?
我正在尝试将数据库名称设置为来自 spring 安全登录页面的请求输入参数。目前我只得到使用 spring security 检索到的用户名SecurityContextHolder.getContext().getAuthentication()
。
如何访问登录页面上设置的附加字段?
有很多方法可以做到这一点,但官方的方法是使用自定义AuthenticationDetails
and ,分别AuthenticationDetailsSource
继承 Spring 的WebAuthenticationDetails
and WebAuthenticationDetailsSource
。将额外字段添加到自定义项WebAuthenticationDetails
,并让自定义WebAuthenticationDetailsSource
项从请求中获取数据以填充该字段。
在 Spring Security 3.1 中,使用元素的authentication-details-source-ref
属性很容易配置。<form-login>
在 3.0 中,您必须使用BeanPostProcessor
. Spring Security FAQ 中有一个关于使用 BeanPostProcessor 配置自定义 WebAuthenticationDetailsSource 的示例。
完成此操作后,您可以调用 SecurityContextHolder.getContext().getAuthentication().getDetails() 来访问您的额外字段。
详细阐述@Vacuum 的评论
这是一个简单的方法(未经测试,但我相信这会奏效)
ExUsernamePasswordAuthenticationFilter
,它将扩展默认过滤器并获取附加参数并将其存储在会话中。它看起来像这样: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);
}
}
UserDetailsService
实施中,修改您的实施:UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException;
获取步骤 1) 中的过滤器提供的会话变量。
<http />
安全设置中,用您的自定义过滤器覆盖默认过滤器<custom-filter ref="beanForYourCustomFilterFromStep1" position="FORM_LOGIN_FILTER"/>
有关自定义过滤器的更多信息,请参阅文档的这一部分:http: //static.springsource.org/spring-security/site/docs/3.1.x/reference/springsecurity-single.html#ns-custom-filters
sourcedelica提到 usingAuthenticationDetailsSource
和 custom AuthenticationDetails
。这是一个例子。
authentication-details-source-ref
将带有 bean id 的属性添加customWebAuthenticationDetailsSource
到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>
创建一个新类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 */ }
}
如果您使用 custom ,有一种更简单的方法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);
}
}
@user1322340 没有提供在 loadUserByUsername 函数中获取会话属性的实现细节:
第 1 步:按照@user1322340 提供的所有步骤进行操作
第 2 步:您需要在 web.xml 中添加一个配置,如下所示:
<listener>
<listener-class>
org.springframework.web.context.request.RequestContextListener
</listener-class>
</listener>
第 3 步:使用此类代码获取属性:
RequestContextHolder.getRequestAttributes().getAttribute("yourAttributeName", RequestAttributes.SCOPE_SESSION);
第 4 步:在 Spring Security 配置中注册您的过滤器。如果您收到错误“必须指定 authenticationManager ”。在配置中注册过滤器后。您需要为扩展过滤器设置一个 authenticationManagerBean 并以这种方式配置它:
@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)
...
}
}
对于使用 java 配置的 spring security 3.0 或更高版本,以下简单步骤效果很好。
在配置中的 HttpSecurity 对象中的 UserNameandPasswordAuthenticationFilter 之前添加您的过滤器。
http.addFilterBefore(new YourFilter(), UsernamePasswordAuthenticationFilter.class);
让过滤器有这样一行来获取会话请求中所需的字段。
if(requestPath != null &&requestPath.equals("/login") ) {
session.setAttribute("yourParam",req.getParameter("yourParam"));
}
稍后您可以从任何类的会话中获取参数值:
String yourParam =(String)request.getSession().getAttribute("yourParam");
简单的方法:
1)注册RequestContextListener
@Bean
public RequestContextListener requestContextListener(){
return new RequestContextListener();
}
2)和主课:
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.
currentRequestAttributes()).
getRequest();
3)之后,我们可以在自定义标头中获取参数:
request.getHeader("OrganizationId")
最简单的方法只需两步:
第1步。
在 web.xml 中添加以下监听器:
<listener>
<listener-class>
org.springframework.web.context.request.RequestContextListener
</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value></param-value>
</context-param>
第2步。
在您想要获取其他参数的类方法中添加以下内容:
RequestAttributes attribs = RequestContextHolder.getRequestAttributes();
if (RequestContextHolder.getRequestAttributes() != null) {
HttpServletRequest request = ((ServletRequestAttributes) attribs).getRequest();
}
现在您可以通过以下方式获取附加参数,假设附加参数名为“loginType”:
request.getParameter("loginType")