没有web.xml的Spring安全自定义身份验证过滤器 [英] Spring security custom authentication filter without web.xml
问题描述
使用注释和java配置我不太清楚如何为弹簧安全性注册一个被覆盖的过滤器。
Using annotation and java configuration it is not quite clear to me how to register an overridden filter for spring security.
我想要实现的是做一个自动登录时不显示登录表单,因为此时用户已经过身份验证。因此,只会读取标题参数并使用spring security进行授权。
What I want to achieve is to do an auto login without showing a Login form since at that time the user will already be authenticated. Therefore will only be reading a header param and use spring security for authorization purposes.
这是我正在尝试的简化版本,Spring安全性正常工作,除了有时显示登录屏幕。
引导BypassLoginFilter是我需要的全部内容。另外在某处读取http auto auto config应该关闭这种行为,但不确定如何在纯java配置中实现。
This is a simplified version of what I'm trying to, and the Spring security works correctly, except for sometimes showing the login screen. Bootstrapping the BypassLoginFilter is all I need to get this going. Also read somewhere that http auto config should be off for this kind of behaviour, but not sure how to implement in pure java configuration.
SecurityWebApplicationInitializer.java
import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;
public class SecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer{
}
SecurityConfig .java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.authentication.logout.LogoutFilter;
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled=true, prePostEnabled=true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/resources/**");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
http.authorizeRequests().antMatchers("/*").permitAll()
.anyRequest().hasRole("USER").and()
.formLogin()
.permitAll();
http.addFilterBefore(new BypassLoginFilter(), LogoutFilter.class);
//.and().anonymous().disable();
}
@Override
@Autowired
protected void registerAuthentication(AuthenticationManagerBuilder auth) {
try {
auth.inMemoryAuthentication().withUser("user").password("password")
.roles("USER").and().withUser("admin").password("password")
.roles("USER", "ADMIN");
} catch (Exception e) {
e.printStackTrace();
}
}
}
BypassLoginFilter.java
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken;
public class BypassLoginFilter extends AbstractAuthenticationProcessingFilter{
private static String HEADER_IS_ADMIN = "isAdmin";
public BypassLoginFilter()
{
super("/*");
}
//Never gets executed
@Override
public Authentication attemptAuthentication(HttpServletRequest request,
HttpServletResponse response) throws AuthenticationException,
IOException, ServletException {
boolean isAdmin = Boolean.valueOf(request.getHeader(HEADER_IS_ADMIN));
PreAuthenticatedAuthenticationToken authRequest = new PreAuthenticatedAuthenticationToken("","",getAuthorities(isAdmin));
authRequest.setDetails(authenticationDetailsSource.buildDetails(request));
return getAuthenticationManager().authenticate(authRequest);
}
private List<GrantedAuthority> getAuthorities(boolean isAdmin)
{
List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
authorities.add(new SimpleGrantedAuthority("ROLE_USER"));
if(isAdmin){
authorities.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
}
return authorities;
}
}
推荐答案
你可以尝试以下方法。假设你有一个 YourUser
类看起来像这样:
You can try following approach. Let's say you have a YourUser
class which looks like that:
public class YourUser extends org.springframework.security.core.userdetails.User{
...
public String getStartPage(){ return "/userhomepage"; }
...
}
然后你需要声明身份验证处理程序:
Then you need to declare authentication handler:
@Component
public class YourAuthenticationSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {
protected String determineTargetUrl(HttpServletRequest request, HttpServletResponse response) {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication.getPrincipal() instanceof YourUser) {
final YourUser user = (YourUser) authentication.getPrincipal();
return user.getStartPage();
}else {
return "/defaultPageForNonAuthenticatedUsers";
}
}
}
并在安全性中使用它配置:
And use it in the security configuration:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// rest calls are ommited
http.successHandler(successHandler());
}
@Bean
public AuthenticationSuccessHandler successHandler() throws Exception {
return new YourAuthenticationSuccessHandler();
}
}
这篇关于没有web.xml的Spring安全自定义身份验证过滤器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!