Bha*_*has 40 spring spring-security
我正在尝试将数据库名称设置为spring security登录页面中的请求输入参数.目前我只获得使用spring security检索的用户名SecurityContextHolder.getContext().getAuthentication().
如何访问登录页面上设置的附加字段?
sou*_*ica 47
有很多方法可以做到这一点,但官方的方法是使用自定义AuthenticationDetails和AuthenticationDetailsSource子类分别为Spring WebAuthenticationDetails和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()来访问您的额外字段.
小智 27
阐述@ Vacuum的评论
这是一个简单的方法(未经测试,但我相信这会有效)
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);
}
}
Run Code Online (Sandbox Code Playgroud)
2)在您的UserDetailsService实现中,修改您的实现:
UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException;
Run Code Online (Sandbox Code Playgroud)
获取步骤1)中的过滤器可用的会话变量.
3)在您的<http />安全设置中,使用您的自定义过滤器覆盖默认过滤器
<custom-filter ref="beanForYourCustomFilterFromStep1" position="FORM_LOGIN_FILTER"/>
Run Code Online (Sandbox Code Playgroud)
有关自定义过滤器的更多信息,请参阅文档的这一部分:http://static.springsource.org/spring-security/site/docs/3.1.x/reference/springsecurity-single.html#ns-custom-filters
Kam*_*kol 23
sourcedelica提到使用AuthenticationDetailsSource和自定义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>
Run Code Online (Sandbox Code Playgroud)
创建一个新类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);
}
}
Run Code Online (Sandbox Code Playgroud)
和相关的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 */ }
}
Run Code Online (Sandbox Code Playgroud)
如果您使用的是 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);
}
}
Run Code Online (Sandbox Code Playgroud)
@ user1322340没有提供实现细节来获取loadUserByUsername函数中的会话属性:
步骤1:遵循@ user1322340提供的所有步骤
步骤2:您需要在web.xml中添加一个配置,如下所示:
<listener>
<listener-class>
org.springframework.web.context.request.RequestContextListener
</listener-class>
</listener>
Run Code Online (Sandbox Code Playgroud)
步骤3:使用以下代码获取属性:
RequestContextHolder.getRequestAttributes().getAttribute("yourAttributeName", RequestAttributes.SCOPE_SESSION);
Run Code Online (Sandbox Code Playgroud)
步骤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)
...
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
60771 次 |
| 最近记录: |