具有Spring Security的多重自定义身份验证

编程入门 行业动态 更新时间:2024-10-24 14:20:52
本文介绍了具有Spring Security的多重自定义身份验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我有一个spring应用程序,该应用程序使用自定义的身份验证过滤器(例如filter1)来授权请求​​,该过滤器使用身份验证管理器进行身份验证,并且适用于应用程序中的所有url.

I have a spring application which uses a custom Authentication Filter say filter1 to authorize the request, this filter uses an authentication manager for authentication and is applicable for all urls in application.

现在,我想实现一个不同的身份验证过滤器,例如filter2,该过滤器必须授权使用url(/api/)进行特殊类型的请求说.这就是所有具有(/api/**)这样的url的请求都必须使用filter2.

Now, I want to implement a different Authentication Filter say filter2 which has to authorize special kind of request say with url (/api/). That is the all the request which has the url like (/api/**) has to use filter2.

下面是到目前为止我为此目的尝试过的代码.

Below is the code I've tried so far for this purpose.

public class SecurityAppConfig { @Configuration @Order(1) public static class APISecurityConfig extends WebSecurityConfigurerAdapter { private CustomAuthenticationManager1 manager1 = new CustomAuthenticationManager1(); @Override protected void configure(HttpSecurity http) throws Exception { http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and() .formLogin().disable().csrf().disable().cors().disable().logout().disable(); if (manager1 != null) { http.addFilterAfter(new Filter1(manager1), AnonymousAuthenticationFilter.class); } } } @Configuration @Order(2) public static class OtherApiSecurityConfig extends WebSecurityConfigurerAdapter { private AuthenticationManager2 manager2 = new AuthenticationManager2(); @Override protected void configure(HttpSecurity http) throws Exception { http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and() .formLogin().disable().csrf().disable().cors().disable().logout().disable(); if (manager2 != null) { http.antMatchers("/api/**").addFilterAfter(new Filter2(manager2), AnonymousAuthenticationFilter.class); } } } }

在应用程序启动时,两个过滤器都已向其管理器注册,但是当此("/api/**")请求到达时,它将转到第一个过滤器进行身份验证,但从不转到第二个过滤器.如果我删除了第一个过滤器,则它可以正常运行,但是会覆盖其他API请求的过滤器.

At the time of app start up both the filter are getting registered with their manager but when this ("/api/**") request comes it goes to the first filter for authentication but never goes to the second filter. If I remove the first filter then it works properly but that would override the filters for other api request.

下面是我实现管理器和过滤器的方式

Below is how I've implemented managers and filters

public class Filter1 extends AbstractAuthenticationProcessingFilter { //implementation omitted for brevity. } public class Filter2 extends AbstractAuthenticationProcessingFilter { //implementation omitted for brevity. } public class AuthenticationManager1 implements AuthenticationManager { //implementation omitted for brevity. } public class AuthenticationManager2 implements AuthenticationManager { //implementation omitted for brevity. }

关于如何使它工作的任何想法.

Any thoughts on how can I get this working.

推荐答案

我认为您的案例不需要两个配置.而且我不明白为什么您需要实现自己的身份验证管理器,甚至其中两个也是如此.我猜您应该改为使用共享身份验证管理器,实现自己的AuthenticationProvider(每种身份验证类型一个),并实现自己的身份验证令牌.除此之外,由于您将AbstractAuthenticationProcessingFilter用作过滤器的基类-您可以在其中设置filterProcessesUrl,因此过滤器知道应将其应用于哪个URL.因此,简而言之:

I don't think that you need two configs for your case. And I don't see why you need to implement your own authentication manager, even two of them. I guess you should use shared authentication manager instead, implement your own AuthenticationProvider (one for each type of authentication), and implement youe own authentication tokens. Besides that, since you're using AbstractAuthenticationProcessingFilter as a base class for you filters - you can set filterProcessesUrl into it, so your filter knows to which URL's it should be applied. So, in brief:

身份验证令牌:

public class MyAuth1AuthenticationToken extends AbstractAuthenticationToken { // Implementation depends on you auth scheme (you can look on // `UsernamePasswordAuthenticationToken` for example) } public class MyAuth2AuthenticationToken extends AbstractAuthenticationToken { // ... }

身份验证提供者:

public class MyAuth1AuthenticationProvider implements AuthenticationProvider { @Override public Authentication authenticate(Authentication authentication) throws AuthenticationException { // Implementation really depends on you auth scheme (you can look on // `AbstractUserDetailsAuthenticationProvider` for example) } @Override public boolean supports(Class<?> authentication) { // By this we're saying that this auth provider is responsible for our MyAuth1 auth request return (MyAuth1AuthenticationToken.class.isAssignableFrom(authentication)); } } public class MyAuth2AuthenticationProvider implements AuthenticationProvider { @Override public Authentication authenticate(Authentication authentication) throws AuthenticationException { // ... } @Override public boolean supports(Class<?> authentication) { return (MyAuth2AuthenticationToken.class.isAssignableFrom(authentication)); } }

过滤器:

public class Auth1Filter extends AbstractAuthenticationProcessingFilter { public Auth1Filter(AuthenticationManager authManager, String defaultFilterProcessesUrl) { super(defaultFilterProcessesUrl); setAuthenticationManager(authManager); } @Override public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException { // extract user info here // ... // populate auth request with your info MyAuth1AuthenticationToken authRequest = new MyAuth1AuthenticationToken(...); // authenticate return this.getAuthenticationManager().authenticate(authRequest); } } public class Auth2Filter extends AbstractAuthenticationProcessingFilter { public Auth2Filter(AuthenticationManager authManager, String defaultFilterProcessesUrl) { super(defaultFilterProcessesUrl); setAuthenticationManager(authManager); } @Override public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException { // extract user info here // ... // populate auth request with your info MyAuth2AuthenticationToken authRequest = new MyAuth1AuthenticationToken(...); // authenticate return this.getAuthenticationManager().authenticate(authRequest); } }

安全配置:

@Configuration public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override public void configure(AuthenticationManagerBuilder auth) throws Exception { // registering our providers auth .authenticationProvider(new MyAuth1AuthenticationProvider()) .authenticationProvider(new MyAuth2AuthenticationProvider()); } @Override protected void configure(HttpSecurity http) throws Exception { http .sessionManagement() .sessionCreationPolicy(SessionCreationPolicy.STATELESS) .and() .formLogin().disable() .csrf().disable() .cors().disable() .logout().disable(); AuthenticationManager authManager = http.getSharedObject(AuthenticationManager.class); http.addFilterAfter(new Auth1Filter(authManager, "/**"), BasicAuthenticationFilter.class); http.addFilterAfter(new Auth2Filter(authManager, "/api/**"), BasicAuthenticationFilter.class); } }

希望有帮助.

更多推荐

具有Spring Security的多重自定义身份验证

本文发布于:2023-11-04 00:51:47,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1556510.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:自定义   身份验证   Spring   Security

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!