spring 如何使用spring security登录页面传递附加参数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10074308/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to pass an additional parameter with spring security login page
提问by Bhas
I am trying to set the database name as the request input parameter from the spring security login page. At present I am only getting username that's been retrieved using spring security SecurityContextHolder.getContext().getAuthentication().
我正在尝试将数据库名称设置为 spring 安全登录页面的请求输入参数。目前我只得到使用 spring security 检索到的用户名SecurityContextHolder.getContext().getAuthentication()。
How to access the additional field that's been set on the login page?
如何访问登录页面上设置的附加字段?
采纳答案by Bhas
Elaborating on @Vacuum's comment
详细说明@Vacuum 的评论
Here's a simple way (untested, but I believe this would work)
这是一个简单的方法(未经测试,但我相信这会奏效)
1) Create a new class ExUsernamePasswordAuthenticationFilterthat will extend the default filter and grab the additional parameter and store it in the session. It will look something like this:
1) 创建一个新类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);
}
}
2) In your UserDetailsServiceimplementation, modify your implementation of:
2) 在您的UserDetailsService实现中,修改您的实现:
UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException;
to grab the session variable that the filter from step 1) makes available.
获取步骤 1) 中过滤器可用的会话变量。
3) in your <http />security set-up, override the default filter with your custom one
3)在您的<http />安全设置中,用您的自定义过滤器覆盖默认过滤器
<custom-filter ref="beanForYourCustomFilterFromStep1" position="FORM_LOGIN_FILTER"/>
Refer to this part of the documentation for more info about custom filters: http://static.springsource.org/spring-security/site/docs/3.1.x/reference/springsecurity-single.html#ns-custom-filters
有关自定义过滤器的更多信息,请参阅文档的这一部分:http: //static.springsource.org/spring-security/site/docs/3.1.x/reference/springsecurity-single.html#ns-custom-filters
回答by sourcedelica
There's a number of ways to do this but the official way to do it is using a custom AuthenticationDetailsand AuthenticationDetailsSource, subclassing Spring's WebAuthenticationDetailsand WebAuthenticationDetailsSource, respectively. Add the extra field to the custom WebAuthenticationDetailsand have the custom WebAuthenticationDetailsSourceget the data from the request to populate the field.
有许多方法可以做到这一点,但它使用的是自做正式的方式AuthenticationDetails与AuthenticationDetailsSource,继承Spring的WebAuthenticationDetails和WebAuthenticationDetailsSource分别。将额外的字段添加到自定义,WebAuthenticationDetails并让自定义WebAuthenticationDetailsSource从请求中获取数据以填充该字段。
In Spring Security 3.1 it's easy to configure by using the authentication-details-source-refattribute of the <form-login>element.
在 Spring Security 3.1 中,很容易通过使用元素的authentication-details-source-ref属性进行配置<form-login>。
In 3.0 you have to use a BeanPostProcessor. There is an example in the Spring Security FAQ on using a BeanPostProcessor to configure a custom WebAuthenticationDetailsSource.
在 3.0 中,您必须使用BeanPostProcessor. Spring Security FAQ 中有一个关于使用 BeanPostProcessor 配置自定义 WebAuthenticationDetailsSource 的示例。
Once this is done then you can call SecurityContextHolder.getContext().getAuthentication().getDetails() to get access to your extra field.
完成此操作后,您可以调用 SecurityContextHolder.getContext().getAuthentication().getDetails() 以访问您的额外字段。
回答by Kamill Sokol
sourcedelicamentioned using AuthenticationDetailsSourceand a custom AuthenticationDetails.
Here is an example.
sourcedelica提到使用AuthenticationDetailsSource和自定义AuthenticationDetails. 这是一个例子。
Add authentication-details-source-refattribute with the bean id customWebAuthenticationDetailsSourceto form-login:
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>
Create a new class CustomWebAuthenticationDetailsSource:
创建一个新类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);
}
}
and the related CustomWebAuthenticationDetails:
和相关的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 */ }
}
回答by Nicholas Lu
@user1322340 does not provide implement detail to get session Attributes in loadUserByUsername function:
@user1322340 没有提供在 loadUserByUsername 函数中获取会话属性的实现细节:
Step 1: Follow all the step provided by @user1322340
第 1 步:按照@user1322340 提供的所有步骤进行操作
Step 2: you need add one configuration in web.xml like this:
第 2 步:您需要在 web.xml 中添加一个配置,如下所示:
<listener>
<listener-class>
org.springframework.web.context.request.RequestContextListener
</listener-class>
</listener>
Step 3: Use such code to get attributes:
第 3 步:使用此类代码获取属性:
RequestContextHolder.getRequestAttributes().getAttribute("yourAttributeName", RequestAttributes.SCOPE_SESSION);
Step 4: Register your filter in spring security config. If you get a error "authenticationManager must be specified". after you register your filter in config. You need set a authenticationManagerBean for your extended filter and config it in that way:
第 4 步:在 spring 安全配置中注册您的过滤器。如果您收到错误“必须指定 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)
...
}
}
回答by GMsoF
There is an easier way if you are using custom AuthenticationProvider. You can just inject HttpServletRequestand retrieve your extra parameter:
如果您使用的是 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);
}
}
回答by user6625940
For spring security 3.0 or above which uses java configuration, the following simple steps works well.
对于使用java配置的spring security 3.0及以上版本,下面的简单步骤效果很好。
Add a your of filter before the UserNameandPasswordAuthenticationFilter in HttpSecurity object in configure.
http.addFilterBefore(new YourFilter(), UsernamePasswordAuthenticationFilter.class);Let the filter has a line like this to get the needed fields in your request to session.
if(requestPath != null &&requestPath.equals("/login") ) { session.setAttribute("yourParam",req.getParameter("yourParam")); }Later you may get the parameter value from the session in any class as:
String yourParam =(String)request.getSession().getAttribute("yourParam");
在配置中的 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");
回答by Игорь Демянюк
Simple way:
简单的方法:
1) register RequestContextListener
1)注册RequestContextListener
@Bean
public RequestContextListener requestContextListener(){
return new RequestContextListener();
}
2) And to main class:
2)到主类:
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.
currentRequestAttributes()).
getRequest();
3) After that we can take params in custom headers:
3) 之后,我们可以在自定义标头中获取参数:
request.getHeader("OrganizationId")
回答by Sanjeev Kumar Gupta
Simplest way in only 2 steps:
最简单的方法,只需两步:
Step 1.
第1步。
Add the following listener in web.xml:
在 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>
Step 2.
第2步。
Add the following in your class method where you want to get additional param:
在您想要获取额外参数的类方法中添加以下内容:
RequestAttributes attribs = RequestContextHolder.getRequestAttributes();
if (RequestContextHolder.getRequestAttributes() != null) {
HttpServletRequest request = ((ServletRequestAttributes) attribs).getRequest();
}
Now you can get your additional parameter by the following, assuming the extra parameter is named "loginType":
现在您可以通过以下方式获取额外参数,假设额外参数名为“loginType”:
request.getParameter("loginType")

