Spring 安全 4. JSON 具有自定义身份验证和授权的 REST

Spring security 4. JSON REST with custom authentication and authorization

我们正在开发 Spring 4 REST/JSON API 但我们需要自定义身份验证服务以针对第 3 方服务进行身份验证。

限制:我们不想要求用户username/password。我们正在使用 "cookie" 进行身份验证(与请求发起者一起发送)。我们需要在后台执行此身份验证过程。 (可能听起来很奇怪,但事实就是如此)。

我们可以使用注册自定义 authentication/authorization 请求过滤器来实现。但这使我们失去了我们计划在以后使用的 spring "authorization" 模块的功能。

所以我们到目前为止所做的,用我们自己的自定义 AuthenticationProviderUserDetailsS​​ervice[=38 编写自定义 WebSecurityConfigurerAdapter =] 但这些配置似乎不起作用。

申请没有进入AuthenticationProvider.authenticate

这是我们的配置。

AuthenticationProvider.java:

@Service
public class AuthenticationService implements AuthenticationProvider, UserDetailsService {

        @Override
    public Authentication authenticate(Authentication auth) throws AuthenticationException {
        // DOESN'T ENTER THIS FUNCTION
        // do authentication stuff
    }


    @Override
    public boolean supports(Class<?> authentication) {
        // JUST FOR TESTING
        return true;
    }


    @Override
    public UserDetails loadUserByUsername(String username)
            throws UsernameNotFoundException {

        // DOESN'T ENTER THIS METHOD
        return null;
    }
}

SecurityConfig.java:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    private static final Logger LOGGER = LoggerFactory.getLogger(SecurityConfig.class);

    @Autowired
    private AuthenticationService authService;

    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/ignoredURL/**");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable() //HTTP with Disable CSRF
                .authorizeRequests()
                    .antMatchers("/api/XYZ/**").hasRole("ADMIN")
                    .anyRequest().authenticated();
        // adding ".httpBasic()" automatically prompts user for username/password
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        // THIS IS NOT TYPO, I use one service implements both interfaces.
        auth.userDetailsService(authService);
        auth.authenticationProvider(authService);
    }


}

通过添加 2 个 classes(过滤器扩展 AbstractPreAuthenticatedProcessingFilter 和另一个 class CustomUser 实现 UserDetails)修复,然后使我的 AuthenticaitonService 实现 spring UserDetailsService 以下是详细信息:

请看what this filter does and how it works

1- 创建 AbcFilter 扩展 spring AbstractPreAuthenticatedProcessingFilter

2- 覆盖 "getPreAuthenticatedPrincipal"。此方法提取了 cookie 值和 return 值。 (无论您 return 这里的对象是什么,您在 UserDetailsService.loadUserByUsername 中作为参数得到的都是什么。

3- 修改我的服务以实现 spring UserDetailsService 并在 loadUserByUsername 内部执行所有身份验证逻辑并在 CustomUser 对象中设置所有登录用户。那就return吧。

4- 只要请求匹配 /api/XYZ/**,Spring 就会调用您的 CustomUser.getAuthorities 并尝试在那里找到 ADMIN 角色。