用于 API 的 Spring webflux 自定义身份验证 [英] Spring webflux custom authentication for API

查看:96
本文介绍了用于 API 的 Spring webflux 自定义身份验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为 Angular 5 应用程序创建 API.我想使用 JWT 进行身份验证.
我想使用 spring security 提供的功能,以便我可以轻松地处理角色.

I am creating an API for an Angular 5 application. I would like to use JWT for authentication.
I would like to use the features that are provided by spring security so I can easily work with roles.

我设法禁用了基本身份验证.但是当使用 http.authorizeExchange().anyExchange().authenticated(); 时,我仍然收到登录提示.
我只想给出 403 而不是提示.因此,通过检查令牌的 Authorization 标头的事物"(它是过滤器吗?)覆盖登录提示.

I managed to disable basic authentication. But when using http.authorizeExchange().anyExchange().authenticated(); I still get a login prompt.
I would like to just give a 403 instead of the prompt. So overriding the login prompt by a "thing"(Is it a filter?) that checks the Authorization header for the token.

我只想在将返回 JWT 令牌的控制器中进行的登录.但是我应该使用什么 spring 安全 bean 来检查用户凭据?我可以构建自己的服务和存储库,但我想尽可能地使用 spring security 提供的功能.

The login I just want to do in a controller that will return a JWT token. But what spring security bean I should use for checking user credentials? I can build my own services and repositories, but I would like to use the features provided by spring security as much as possible.

这个问题的简短版本是:
如何自定义 Spring Security 的身份验证?
我必须创建哪些 bean?
我必须把配置放在哪里?(我现在有一个 SecurityWebFilterChain 的 bean)

The short version of this question is just:
How can I customize spring security's authentication?
What beans do I have to create?
Where do I have to put the configuration? (I now have a bean of SecurityWebFilterChain)

我能找到的关于 webflux 中使用 spring 安全性进行身份验证的唯一文档是:https://docs.spring.io/spring-security/site/docs/5.0.0.BUILD-SNAPSHOT/reference/htmlsingle/#jc-webflux

The only documentation I could find about authentication in webflux with spring security is this: https://docs.spring.io/spring-security/site/docs/5.0.0.BUILD-SNAPSHOT/reference/htmlsingle/#jc-webflux

推荐答案

经过大量的搜索和尝试,我想我已经找到了解决方案:

After a lot of searching and trying I think I have found the solution:

您需要一个包含所有配置的 SecurityWebFilterChain bean.
这是我的:

You need a bean of SecurityWebFilterChain that contains all configuration.
This is mine:

@Configuration
public class SecurityConfiguration {

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private SecurityContextRepository securityContextRepository;

    @Bean
    public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
        // Disable default security.
        http.httpBasic().disable();
        http.formLogin().disable();
        http.csrf().disable();
        http.logout().disable();

        // Add custom security.
        http.authenticationManager(this.authenticationManager);
        http.securityContextRepository(this.securityContextRepository);

        // Disable authentication for `/auth/**` routes.
        http.authorizeExchange().pathMatchers("/auth/**").permitAll();
        http.authorizeExchange().anyExchange().authenticated();

        return http.build();
    }
}

我已禁用 httpBasic、formLogin、csrf 和注销,以便我可以进行自定义身份验证.

I've disabled httpBasic, formLogin, csrf and logout so I could make my custom authentication.

通过设置 AuthenticationManagerSecurityContextRepository,我覆盖了默认的 spring 安全配置,用于检查用户是否通过了请求的身份验证/授权.

By setting the AuthenticationManager and SecurityContextRepository I overridden the default spring security configuration for checking if a user is authenticated/authorized for a request.

身份验证管理器:

@Component
public class AuthenticationManager implements ReactiveAuthenticationManager {

    @Override
    public Mono<Authentication> authenticate(Authentication authentication) {
        // JwtAuthenticationToken is my custom token.
        if (authentication instanceof JwtAuthenticationToken) {
            authentication.setAuthenticated(true);
        }
        return Mono.just(authentication);
    }
}

我不完全确定身份验证管理器的用途,但我认为进行最终身份验证,因此在一切正常时设置 authentication.setAuthenticated(true);.

I am not fully sure where the authentication manager is for, but I think for doing the final authentication, so setting authentication.setAuthenticated(true); when everything is right.

SecurityContextRepository:

SecurityContextRepository:

@Component
public class SecurityContextRepository implements ServerSecurityContextRepository {

    @Override
    public Mono<Void> save(ServerWebExchange serverWebExchange, SecurityContext securityContext) {
        // Don't know yet where this is for.
        return null;
    }

    @Override
    public Mono<SecurityContext> load(ServerWebExchange serverWebExchange) {
        // JwtAuthenticationToken and GuestAuthenticationToken are custom Authentication tokens.
        Authentication authentication = (/* check if authenticated based on headers in serverWebExchange */) ? 
            new JwtAuthenticationToken(...) :
            new GuestAuthenticationToken();
        return new SecurityContextImpl(authentication);
    }
}

在加载中,我将根据 serverWebExchange 中的标头检查用户是否已通过身份验证.我使用 https://github.com/jwtk/jjwt.无论用户是否通过身份验证,我都会返回不同类型的身份验证令牌.

In the load I will check based on the headers in the serverWebExchange if the user is authenticated. I use https://github.com/jwtk/jjwt. I return a different kind of authentication token if the user is authenticated or not.

这篇关于用于 API 的 Spring webflux 自定义身份验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆