栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Spring Security系列(一):自定义AuthenticationFilter

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Spring Security系列(一):自定义AuthenticationFilter

Spring Security is a powerful and highly customizable authentication and access-control framework. It is the de-facto standard for securing Spring-based applications.

Spring Security是一个功能强大且高度可定制的身份验证和访问控制框架。它是保护基于Spring的应用程序的事实标准。 

Spring Security is a framework that focuses on providing both authentication and authorization to Java applications. Like all Spring projects, the real power of Spring Security is found in how easily it can be extended to meet custom requirements.

Spring Security是一个专注于为Java应用程序提供身份验证和授权的框架。与所有Spring项目一样,Spring Security的真正威力在于它可以非常容易地扩展以满足定制需求。

Spring Security的核心是一组过滤器链,WebSecurityConfiguration配置类中定义了过滤器链

@Configuration
public class WebSecurityConfiguration implements importAware, BeanClassLoaderAware {

    @Bean(name = AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME)
	public Filter springSecurityFilterChain() throws Exception {
		boolean hasConfigurers = webSecurityConfigurers != null
				&& !webSecurityConfigurers.isEmpty();
		if (!hasConfigurers) {
			WebSecurityConfigurerAdapter adapter = objectObjectPostProcessor
					.postProcess(new WebSecurityConfigurerAdapter() {
					});
			webSecurity.apply(adapter);
		}
		return webSecurity.build();
	}
}

实际项目可以通过继承WebSecurityConfigurerAdapter并重写configure(HttpSecurity http)方法自定义过滤器链的生成,然后通过configure(AuthenticationManagerBuilder auth)方法添加AuthenticationProvider自定义类实现认证逻辑的自定义。

@EnableWebSecurity
@EnableGlobalMethodSecurity(
        prePostEnabled = true
)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

       @Autowired
    private AuthenticationEntryPoint authenticationEntryPoint;

    @Autowired
    private TokenAuthenticationProvider tokenAuthenticationProvider;

    
    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http.exceptionHandling()
                .authenticationEntryPoint(authenticationEntryPoint)
                //.accessDeniedHandler() 
                .and()
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS) 
                .and()
                .authorizeRequests()
                .antMatchers("/token").permitAll()
                .anyRequest().authenticated();
        //添加自定义过滤器 FilterComparator 类标识了过滤器的执行顺序
        //自定义认证过滤器需要放置在UsernamePasswordAuthenticationFilter之前
        http.addFilterBefore(tokenFilter(), UsernamePasswordAuthenticationFilter.class);
    }

    
    @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(tokenAuthenticationProvider);
    }

    @Bean
    public TokenAuthenticationProcessingFilter tokenFilter() {
        return new TokenAuthenticationProcessingFilter();
    }
}

自定义TokenAuthenticationProcessingFilter

public class TokenAuthenticationProcessingFilter extends oncePerRequestFilter {

    public static final String AUTHORIZATION = "Authorization";

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
            FilterChain filterChain) throws ServletException, IOException {
        String authToken = request.getHeader(AUTHORIZATION);
        if(!StringUtils.isEmpty(authToken)){
            authToken = authToken.startsWith("Bearer ") ? authToken.split(" ")[1] : authToken;
            UsernamePasswordAuthenticationToken authenticationToken =
                    new UsernamePasswordAuthenticationToken(authToken, "");
            //自定义Filter的核心方法 绑定AuthenticationToken至SecurityContext
            SecurityContextHolder.getContext().setAuthentication(authenticationToken);
        }
        filterChain.doFilter(request, response);
    }
}

AuthenticationProvider的实现类需要重写自定义认证逻辑方法和支持AbstractAuthenticationToken的类型

@Component
public class TokenAuthenticationProvider implements AuthenticationProvider {
    @Override public Authentication authenticate(Authentication authentication)
            throws AuthenticationException {
        String token = (String) authentication.getPrincipal();
        UsernamePasswordAuthenticationToken result = null;
        //token校验 可以是JWT token 签名的校验
        if ("auth-token".equals(token)) {
         
            result = new UsernamePasswordAuthenticationToken(token, authentication.getCredentials(),
                    Collections.singletonList(() -> "user"));
        }
        return result;
    }

    @Override public boolean supports(Class authentication) {
        return UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication);
    }
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/786208.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号